__setattr__ 和 __dict__ 之间的区别

Wyn*_*ter 5 python python-3.x

如果我想为实例设置一个属性?

我可以使用__setattr__(key, value) self.__dict__[key]=value

我想知道如何__setattr__工作,如果__setattr__只是设置 k,v in __dict__,两种方式有什么区别?setattr 存在的意义是什么?

小智 6

__setattr__(key, value)是被 调用的函数setattr(instance, key, value)

__setattr__(key, value)通常,除非函数中的self.__dict__[key]= value类和方法已以某种方式被覆盖,否则其行为相同。__setattr__

这可能会有所帮助:文档

class MyClass(object):
    def __setattr__(self, key, value):
        print(f"setting {key}={value}")

if __name__ == "__main__":
    m = MyClass()
    m.a = 3
    m.b = 6
    m.__dict__.update({"c": 7})
    print(f"{m.c=}")
    print(f"{m.__dict__=}")
Run Code Online (Sandbox Code Playgroud)
<script src="https://modularizer.github.io/pyprez/pyprez.min.js"></script>
Run Code Online (Sandbox Code Playgroud)


ror*_*rra 6

while__dict__是一个包含所有内部变量的内部字典,__setattr__实际上是一个在您尝试设置属性时始终会调用的方法,因此,您可以拦截这些操作并据此采取行动。

示例代码可以帮助您了解差异:

class Foo:
    def __setattr__(self, key, value):
        print(f'Setting {key} to {value}')
        self.__dict__[key] = value

f = Foo()
f.__dict__['test'] = 1
f.__setattr__('test', 2)
f.test = 3
Run Code Online (Sandbox Code Playgroud)

输出将是:

Setting test to 2
Setting test to 3
Run Code Online (Sandbox Code Playgroud)

而原因是,通过访问__dict__,您是直接访问内部对象字典,而__setattr__跳过了该方法。