首页 > 解决方案 > 如何动态生成属性?

问题描述

我正在使用下面的python代码:

class A(object):
   def __getattr__(self, name):
       print "__getattr__ : %s" % name
       setattr(self, name, A())
       print self.__dict__
       print getattr(self, name)

 x = A()
 x.a = 1 .  # Works fine.
 print x.a

 x.b.c = 2 # Throws error.
 print x.b.c

最后一部分抛出以下错误:

NoneType object has no attribute c.

谁能解释上面代码中的错误是什么,print self.__dict__清楚地表明两者a都已b插入到对象的字典中。

我的用例是拥有一个可以在需要时动态添加其属性的对象。就像我应该能够使用:

x = A()
x.a = 1
x.b.c = 2
x.d.e.f.g = 3

另外,还有其他方法可以实现我的目标吗?

更新:发现错误,__getattr__应该返回一个值。

正确的代码

class A(object):
   def __getattr__(self, name):
       print "__getattr__ : %s" % name
       x = A()
       setattr(self, name, x)
       print self.__dict__
       print getattr(self, name)
       return x # getattr(self, name)

 x = A()
 x.a = 1 .  # Works fine.
 print x.a

 x.b.c = 2 # Works fine.
 print x.b.c

标签: pythonobjectattributespython-2.x

解决方案


__getattr__当一个属性被请求获取但在被请求的对象中不可用时被调用。

假设x没有a,像这样的电话

result = x.a

在功能上等同于

result = getattr(x, "a")

这在功能上等同于

result = type(x).__getattr__(x, "a")

这通常与

result = x.__getattr__("a")

__getattr__最后两个变体仅在绑定到对象而不是类时才有所不同(这可能不起作用

正如您在此处看到的,__getattr__应该返回应该具有的值a

也可以直接设置属性,让后续的get请求不再调用__getattr__,直接由Python处理。这是否有意义(在您的用例中确实如此)取决于特定的用例。

x.b.c = 2通常在这里翻译成类似的东西

setattr(x.__getattr__("b"), "c", 2)

同样,__getattr__必须在此处返回c设置了属性的对象。


推荐阅读