I have a descriptor class X
here. I try to use the descriptor X
in another class Y
class X:
def __init__(self, value):
self.value = value
def __get__(self, instance, owner):
print('#### X.__get__ ####')
return self.value
def __set__(self, instance, value):
print('#### X.__set__ ####')
self.value = value
class Y:
def __init__(self):
self.x = X(10)
y = Y()
print(y.x)
y.x = 20
I was hoping that the statement print(y.x)
would invoke x.__get__
and the statement y.x = 20
would invoke x.__set__
, but it doesn't happen. When I run the above program, I just get this output.
<__main__.X object at 0x7fc65f947950>
Why were the descriptor methods not invoked?
To get the descriptor protocol methods invoked, you need to put the descriptor instance (X()
in your case) on the Y
class, not on the instance. This is described in some detail in the Descriptor HowTo Guide by Raymond Hettinger:
For objects, the machinery is in
object.__getattribute__()
which transformsb.x
intotype(b).__dict__['x'].__get__(b, type(b))
.
Note how b.x
is transformed into the invocation of the descriptor obtained by dict access of type(b)
. The Y
class should look like this:
class Y:
x = X(10)
However, since a single instance of X
will be shared by all instances of Y
, the X
descriptor class will need to be modified to get and set the values from instance
rather than from self
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With