我想更好地理解描述符。
我不明白为什么在foo方法中,描述符 __get__
方法不会被调用。
据我理解描述符,当我通过点运算符或使用__get__
访问objects属性时,总会调用 __getattribute__()
方法。
class RevealAccess(object):
def __init__(self, initval=None, name='var'):
self.val = initval
self.name = name
def __get__(self, obj, objtype):
print('Retrieving', self.name)
return self.val
def __set__(self, obj, val):
print('Updating', self.name)
self.val = val
class MyClass(object):
x = RevealAccess(10, 'var "x"')
y = 5
def foo(self):
self.z = RevealAccess(13, 'var "z"')
self.__getattribute__('z')
print(self.z)
m = MyClass()
m.foo()
m.z # no print
m.x # prints var x
答案 0 :(得分:6)
z
是实例上的属性,而不是类。描述符协议仅适用于从类中检索的属性。
对于对象,机器位于
object.__getattribute__()
,将b.x
转换为type(b).__dict__['x'].__get__(b, type(b))
。
并在Python数据模型的Implementing Descriptors section中:
以下方法仅适用于包含该方法的类的实例(所谓的描述符类)出现在所有者类中(描述符必须在所有者的类字典或其父级之一的类字典中)。
你的m.z
在课堂词典中找不到; type(m).__dict__['z']
不存在;它可以在m.__dict__['z']
中找到。此处m
是实例,所有者类是MyClass
,而z
未出现在所有者类字典中。< / p>