Python,如何在属于重载方法的类的字典对象上使用 __setattr__ ?

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)

Dha*_*ara 4

b.hello打印字符串“err”,因为它datastore是类本身的属性,而不是类对象的属性。因此,当你在初始化它时ab也可以访问它。

\n\n

datastore = {}因此,从类中删除。

\n\n

此外,来自Python文档

\n\n
\n

如果__setattr__()想要分配给实例属性,则不应简单地执行self.name = value\xe2\x80\x94,否则会导致对其自身的递归调用。相反,它应该将值插入到实例属性的字典中,例如self.__dict__[name] = value。对于新式类,不应访问实例字典,而应调用基类的同名方法,例如 object.__setattr__(self, name, value)

\n
\n\n

因此,将您的代码更改为:

\n\n
class 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\n
Run Code Online (Sandbox Code Playgroud)\n