了解 Python 个描述符
Understanding Python Descriptors
我正在努力更好地理解描述符。
我不明白为什么在 foo 方法中没有调用描述符 __get__
方法。
据我了解描述符,当我通过点运算符访问对象属性或使用 __getattribute__()
时,总是会调用 __get__
方法。
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
z
是 实例 上的属性,而不是 class 上的属性。描述符协议仅适用于从 class.
检索到的属性
For objects, the machinery is in object.__getattribute__()
which transforms b.x
into type(b).__dict__['x'].__get__(b, type(b))
.
并且在 Python 数据模型的 Implementing Descriptors section 中:
The following methods only apply when an instance of the class containing the method (a so-called descriptor class) appears in an owner class (the descriptor must be in either the owner’s class dictionary or in the class dictionary for one of its parents).
在class字典中找不到您的m.z
; type(m).__dict__['z']
不存在;它位于 m.__dict__['z']
中。这里m
是实例,所有者class是MyClass
,z
没有出现在所有者 class 字典。
我正在努力更好地理解描述符。
我不明白为什么在 foo 方法中没有调用描述符 __get__
方法。
据我了解描述符,当我通过点运算符访问对象属性或使用 __getattribute__()
时,总是会调用 __get__
方法。
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
z
是 实例 上的属性,而不是 class 上的属性。描述符协议仅适用于从 class.
For objects, the machinery is in
object.__getattribute__()
which transformsb.x
intotype(b).__dict__['x'].__get__(b, type(b))
.
并且在 Python 数据模型的 Implementing Descriptors section 中:
The following methods only apply when an instance of the class containing the method (a so-called descriptor class) appears in an owner class (the descriptor must be in either the owner’s class dictionary or in the class dictionary for one of its parents).
在class字典中找不到您的m.z
; type(m).__dict__['z']
不存在;它位于 m.__dict__['z']
中。这里m
是实例,所有者class是MyClass
,z
没有出现在所有者 class 字典。