制作 __dict__ A 属性
Making __dict__ A Property
为什么这样做:
class Bunch(dict):
def __init__(self, *args, **kwargs):
super(Bunch, self).__init__(*args, **kwargs)
self.__dict__ = self
b = Bunch()
b["a"] = 1
print(b.a)
尽管有循环引用:
import sys
print(sys.getrefcount(b))
# ref count is 3 when normally it is 2
但不是这个:
class Bunch(dict):
@property
def __dict__(self):
return self
b = Bunch()
b["a"] = 1
b.a
# raises AttributeError
虽然 __dict__
是大多数外观的属性,但在幕后实施了一些特殊行为,绕过了 property
创建的描述符逻辑。
默认的__dict__
属性已经基本是一个属性。 (不是字面上的property
,而是通过描述符协议实现的,就像property
一样。)
当您设置 self.__dict__ = self
时,它会通过 __dict__
描述符的 __set__
方法并替换用于实例属性的字典。
然而,Python在执行属性操作时不使用__dict__
描述符来查找实例字典;它使用不同的内部机制。因此,创建您自己的 __dict__
描述符不会影响第二个示例中 b.a
的属性查找机制。
为什么这样做:
class Bunch(dict):
def __init__(self, *args, **kwargs):
super(Bunch, self).__init__(*args, **kwargs)
self.__dict__ = self
b = Bunch()
b["a"] = 1
print(b.a)
尽管有循环引用:
import sys
print(sys.getrefcount(b))
# ref count is 3 when normally it is 2
但不是这个:
class Bunch(dict):
@property
def __dict__(self):
return self
b = Bunch()
b["a"] = 1
b.a
# raises AttributeError
虽然 __dict__
是大多数外观的属性,但在幕后实施了一些特殊行为,绕过了 property
创建的描述符逻辑。
默认的__dict__
属性已经基本是一个属性。 (不是字面上的property
,而是通过描述符协议实现的,就像property
一样。)
当您设置 self.__dict__ = self
时,它会通过 __dict__
描述符的 __set__
方法并替换用于实例属性的字典。
然而,Python在执行属性操作时不使用__dict__
描述符来查找实例字典;它使用不同的内部机制。因此,创建您自己的 __dict__
描述符不会影响第二个示例中 b.a
的属性查找机制。