I know that I can dynamically add an instance method to an object by doing something like:
import types
def my_method(self):
# logic of method
# ...
# instance is some instance of some class
instance.my_method = types.MethodType(my_method, instance)
Later on I can call instance.my_method() and self will be bound correctly and everything works.
Now, my question: how to do the exact same thing to obtain the behavior that decorating the new method with @property would give?
I would guess something like:
instance.my_method = types.MethodType(my_method, instance)
instance.my_method = property(instance.my_method)
But, doing that instance.my_method returns a property object.
The
propertydescriptor objects needs to live in the class, not in the instance, to have the effect you desire. If you don’t want to alter the existing class in order to avoid altering the behavior of other instances, you’ll need to make a “per-instance class”, e.g.:I’m marking these special “per-instance” classes with an attribute to avoid needlessly making multiple ones if you’re doing several
addpropcalls on the same instance.Note that, like for other uses of
property, you need the class in play to be new-style (typically obtained by inheriting directly or indirectly fromobject), not the ancient legacy style (dropped in Python 3) that’s assigned by default to a class without bases.