Reputation: 2471
I have a class with one property
. I also have a setter for that property. How can I get the bound method for the property.setter
?
Why I'm Asking
With normal methods, this is easy. One can just use class_instance.method_name
.
However, I'm having a tough time figuring this out for property
, since it returns a descriptor object.
Example Code
This was written with Python 3.6
:
class SomeClass:
def __init__(self):
self._some_attr = 0
@property
def some_attr(self) -> int:
return self._some_attr
# How can I get this bound method?
@some_attr.setter
def some_attr(self, val: int) -> None:
self._some_attr = val
def normal_method(self, val: int) -> None:
self.some_attr = val
if __name__ == "__main__":
some_class = SomeClass()
print(some_class.some_attr) # prints: 0
print(some_class.normal_method) # prints: bound method SomeClass.normal_method
Upvotes: 1
Views: 1491
Reputation: 106995
In the documentation of Python descriptor, you can find the equivalent implementation of the property
descriptor in pure Python, where the setter method simply calls the unbound method with the given object and target value:
def __set__(self, obj, value):
if self.fset is None:
raise AttributeError("can't set attribute")
self.fset(obj, value) # unbound method called
In other words, no bound method is actually created when you use the property setter, so there is no way to "get" the bound method when it does not actually exist.
However, you can create such a bound method of a given instance for a given unbound method, in this case the setter attribute of the property
descriptor, SomeClass.some_attr.fset
, using the types.MethodType
constructor:
from types import MethodType
some_class = SomeClass()
f = MethodType(SomeClass.some_attr.fset, some_class)
print(f)
f(2) # calls the bound setter method, equivalent to: some_class.some_attr = 2
print(some_class.some_attr)
This outputs:
<bound method SomeClass.some_attr of <__main__.SomeClass object at 0x0000015C3CCB74C0>>
2
Upvotes: 1