简体   繁体   中英

Python how to get bound method of some property.setter

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM