python - 如何动态生成属性?
问题描述
我正在使用下面的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
解决方案
__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
设置了属性的对象。
推荐阅读
- android - Cordova-plugin-facebook4 - 无法构建离子应用程序
- html - 为什么将 h1 标签放在 div 标签中时,div 标签之间有空格?
- android - 该项目不是基于 Gradle 的项目。如何从根目录打开项目?
- django - 使用 Django ArrayField 存储日期和值
- java - 如何在使用 TestNG 和 Java 的方法执行期间设置调用计数
- java - 列表的使用
- javascript - Javascript - Mongodb Collection 的模型查找方法不适用于过滤条件
- json - 可解码 JSONDecoder 处理相同值的不同编码键
- r - 如何在 readline() 中自动输入输入,而不是在 R 的控制台中手动输入?
- azure-devops - 使用 VSTS 扩展创建新的工作项类型