sow*_*owa 5 python setattr python-2.7
如下面的代码所示,为什么我不能__setattr__在属于重载该方法的类的字典上设置值?我预计那b.hello不会存在。
class MyClass():
datastore = {}
def __init__(self):
self.datastore = {}
def __getattr__(self, key):
return self.datastore[key]
def __setattr__(self, key, value):
self.datastore[key] = value
a = MyClass()
b = MyClass()
a.hello = "err"
print a.hello # err
print b.hello # err
Run Code Online (Sandbox Code Playgroud)
b.hello打印字符串“err”,因为它datastore是类本身的属性,而不是类对象的属性。因此,当你在初始化它时a,b也可以访问它。
datastore = {}因此,从类中删除。
此外,来自Python文档:
\n\n\n\n\n如果
\n__setattr__()想要分配给实例属性,则不应简单地执行self.name = value\xe2\x80\x94,否则会导致对其自身的递归调用。相反,它应该将值插入到实例属性的字典中,例如self.__dict__[name] = value。对于新式类,不应访问实例字典,而应调用基类的同名方法,例如object.__setattr__(self, name, value)。
因此,将您的代码更改为:
\n\nclass MyClass(object): # Use new style classes\n def __init__(self):\n object.__setattr__(self, \'datastore\', {}) # This prevents infinite recursion when setting attributes\n\n def __getattr__(self, key):\n return self.datastore[key]\n\n def __setattr__(self, key, value):\n self.datastore[key] = value\n\na = MyClass()\nb = MyClass()\n\na.hello = "err"\n\nprint a.hello # Works\nprint b.hello # Gives an error\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
8506 次 |
| 最近记录: |