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.xintotype(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