有这段代码:
class A:
def __init__(self, x):
self.x = x
def __get__(self, obj, type=None):
print("__get__")
return self.x
def __set__(self, obj, value):
pass
class B:
a_oc = A(44)
def __init__(self, y):
self.a_ob = A(y)
b = B(3)
print(b.a_oc) # class attribute called __get__
print(b.a_ob) # __get__ not called
对于类属性__get__
被调用,例如属性不是。为什么呢?
答案 0 :(得分:2)
新类型的属性查找规则(3.x中的类和继承自2.x中的对象的类)是obj.attr
:
如果该值由Python生成,例如__hash__
,则将其返回
在obj.__class__.__dict__
中查找,如果存在且存在__get__
,则返回attr.__get__(obj, obj.__class__)
的结果,如果不存在,则递归查找父类。
在obj.__dict__
中查找。如果obj
是实例并且attr存在,则返回它或下一步。如果obj
是一个类,则查找其自身,其父项为__dict__
,如果是描述符,则返回attr.__get__(None, obj.__class__)
或attr本身。
在obj.__class__.__dict__
中查找。如果attr是非数据描述符,则返回它的结果。如果它存在,则返回attr本身。
引发AttributeError
见上课:
>>> b.__class__
<class 'des.B'>
>>> b.__class__.__dict__
mappingproxy({'__init__': <function B.__init__ at 0x7f2dacb4e290>, '__doc__': None, '__weakref__': <attribute '__weakref__' of 'B' objects>, '__dict__': <attribute '__dict__' of 'B' objects>, 'a_oc': <des.A object at 0x7f2dacb5de50>, '__module__': 'des', '__qualname__': 'B'})
>>>
>>> b.__dict__
{'a_ob': <des.A object at 0x7f2dacb5df10>}
>>>
b.a_oc
符合第2步,b.a_ob
符合第3步。我将您的代码放在模块des
中。