Given an object foo (to which i have access) of class A (to which i have no access).
foo has an attribute x, which is accessed by alot of parties which can also set foo.x.
Is it somehow possible to replace foo.x with a @property-like such that assignments like
foo.x = "bar"
Will from then on invoke a function specified by me? If so, is it also possible to remove this property afterwards and replace it with something like e.g foo.x = "not a property" again?
Please consider: I have no access to the class but only to the object.
You can't put properties on an instance, no. You'll have to monkey-patch the class, or subclass it.
Monkey-patching would require you to store the original attribute somewhere on the instance still, using a different name:
def getter(self):
try:
return self._x
except AttributeError:
# access the attribute on the instance directly.
try:
return self.__dict__['x']
except KeyError:
raise AttributeError('x')
def setter(self, value):
self._x = value
foo._x = foo.x
type(foo).x = property(getter, setter)
This sets the property object on the class. Now all instances of that class will have that property! To deal with this, the getter above falls back to trying to get the original x attribute value from the instance __dict__ if no _x attribute is present. This should ensure that existing instances continue to work.
Removing the property is as simple as deleting it:
del type(foo).x
Note that this will conflict with a class attribute (e.g. if type(foo).x is an existing object).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With