问题
As the official demo described here, the following code will print Retrieving var "x"
.
class RevealAccess(object):
"""A data descriptor that sets and returns values
normally and prints a message logging their access.
"""
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 MyClass1(object):
x = RevealAccess(10, 'var "x"')
MyClass1().x
But if x
is an instance variable, the data descriptor machinery will not work, the following code will not print anything.
class MyClass2(object):
def __init__(self):
self.x = RevealAccess(10, 'var "x"')
MyClass2().x
And, if I implements the data descriptor machinery manually as described here, the following code will Retrieving var "x"
again.
class MyClass3(object):
def __init__(self):
self.x = RevealAccess(10, 'var "x"')
def __getattribute__(self, key):
"Emulate type_getattro() in Objects/typeobject.c"
v = object.__getattribute__(self, key)
if hasattr(v, '__get__'):
return v.__get__(None, self)
return v
MyClass3().x
So, is the default data descriptor machinery not implemented as the doc described?
I am using python 2.7.10.
回答1:
The descriptor how-to is wrong here. The Python data model has the correct description:
The following methods [
__get__
,__set__
, and__delete__
] 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).
Descriptors have to be class attributes.
来源:https://stackoverflow.com/questions/36932396/python-data-descriptor-did-not-work-as-instance-variable