Why aren't Python descriptor methods called when called with obj.x syntax?

I have an X descriptor class here. I am trying to use 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(yx) yx = 20 

I was hoping that the print(yx) statement would call x.__get__ , and the yx = 20 statement would call x.__set__ , but that would not happen. When I run the above program, I just get this output.

 <__main__.X object at 0x7fc65f947950> 

Why weren't descriptor methods called?

+5
source share
1 answer

To call the descriptor protocol methods, you need to put the instance of the descriptor ( X() in your case) in the Y class , not in the instance. This is described in detail in the Descriptor Description Guide by Raymond Hettinger:

For objects, the mechanism is in object.__getattribute__() , which converts bx to type(b).__dict__['x'].__get__(b, type(b)) .

Notice how bx converted to a descriptor call obtained by accessing type(b) . Class Y should look like this:

 class Y: x = X(10) 

However, since one instance of X will be used by all instances of Y , the X descriptor class will need to be modified to get and set values ​​from instance , not from self >.

+3
source

Source: https://habr.com/ru/post/1211944/


All Articles