I have a following (simplified of course) descriptor:
class d:
def __init__(self, method):
self.method = method
def __get__(self, instance, owner=None):
print(instance, owner, self.method)
return self.method(instance)
In __get__() I want to access the class where the decorated function is defined, but the owner argument is B on both invocations of __get__() that happen in the following code:
class A:
@d
def f(self):
return "A"
class B(A):
@d
def f(self):
return super().f + "B"
print(B().f)
I've checked the Descriptor HowTo Guide section on calling descriptors via super() and it says that this invocation indeed passes the subclass type to the parent class __get__(). Does it suggest I may need to define __getattribute__() to get what I want, or is there a different way? I understand that the super() call doesn't just return A but a proxy for B but I feel like there should be a way to get A in the descriptor.
I'll also appreciate a clearer explanation of what is happening in my code.
The easier thing to do is to record, in the descriptor, the class where it is defined at class creation time.
Since Python 3.6 that is possible due to the addition of the
__set_name__method to the descriptor protocol.The
ownerparameter received in__set_name__is the actuall class where the descriptor is defined. It can then be set as a descriptor attribute:And running this along with your example
AandB:Without the resort to
__set_name__the thing to do would be indeed to walk linearly through the__mro__until it would findself, as long as it had not been shadowed by another decorator of the same kind: