Your descriptors are not being called, and there is no way to write a descriptor or anything else to do what you seem to want.
When you do num = 2
, you have thrown away your Number
object and set the variable num
to the ordinary number 2. When you then add 7 to it, it equals 9, because it's just a regular number. Your Number
class is not involved in any way.
Descriptors allow you to hook into what happens when you do obj.foo
or obj.foo = blah
. In these cases it is foo
that is the descriptor, not obj
, and the descriptor only works when it is an attribute. There is no way to change what happens when you do obj = blah
, where obj
is a bare name (i.e., no dots or []
). In relation to your guess:
get
- When use obj.prop to get property and the prop is another object which is setting descriptor
- Yes, basically. When you do
obj.prop
andprop
is a descriptor, then its__get__
is called. Note thatprop
is the descriptor, notobj
.
- Yes, basically. When you do
- when calculate some expression should get value such as
a + 5
. If a is have descriptor and will call__get__
- No. You can override such behavior with the
__add__
magic method, or similar methods for other operators
- No. You can override such behavior with the
- If a object simulate a function will call
__get__
to get function body first, and then call__call__
to run the function.- I don't understand what this means, but I think no. If the object defines
__call__
, thenobj()
calls its__call__
without involving any descriptor.
- I don't understand what this means, but I think no. If the object defines
- When use obj.prop to get property and the prop is another object which is setting descriptor
set
- When the object appear in the left side of assignment statement such as
obj = 5
- No. Only when the descriptor is accessed as an attribute on the left side, as in
obj.prop = 5
, where prop is a descriptor.
- No. Only when the descriptor is accessed as an attribute on the left side, as in
- When the object appear in the left side of assignment statement such as
The bottom line is that descriptors only work when they are attributes of classes. Just creating a "bare" descriptor as you're trying to do (i.e., doing obj = SomeDescriptorClass()
) won't do anything.
Also, as a side note, descriptors only work when set on new-style classes. If you're using Python 2, this means that the class holding the descriptor has to inherit from object
.