I would like to add some small functionality to a method of another class' instance. What I tried is listed below. With the same approach it's possible to completely change the method. But I would like to keep a slightly altered version of the original method. Is that possible?
BTW: The classes can not inherit from one another, because I don't necessarily know what class B is.
class A:
def alter_fn(self, obj):
def wrapper():
func = getattr(obj, obj.fn_name)
out = func()
print('out = ', out)
return out
setattr(obj, obj.fn_name, wrapper)
return
class B:
def __init__(self) -> None:
self.fn_name = 'fn'
def fn(self):
return 123
a=A()
b=B()
a.alter_fn(b)
b.fn()
For obvious reasons this raises a recursion depth error but I do not know how to avoid that. I also tried func = copy(getattr(obj, obj.fn_name))
After altering the method b.fn I would like it to return the value, the unaltered function would return (here 123) but I would also like it to do something else with this output, in this example print it.
Move the assignment of func
above the definition of wrapper
.
...
def alter_fn(self, obj):
func = getattr(obj, obj.fn_name)
def wrapper():
...
This way getattr
is called only once and wrapper
can access func
as a closure variable.
You just need to take the func = getattr(obj, obj.fn_name)
out of the wrapper
function.
class A:
def alter_fn(self, obj):
func = getattr(obj, obj.fn_name)
def wrapper():
out = func()
print('out = ', out)
return out
setattr(obj, obj.fn_name, wrapper)
return
You need to get the wrapped function before re-assigning it:
def alter_fn(self, obj):
func = getattr(obj, obj.fn_name)
def wrapper():
out = func()
print('out = ', out)
return out
setattr(obj, obj.fn_name, wrapper)
return
This way func
is assigned only once, when the original function is called. Thus, you can safely call it without calling wrapper()
again by accident.
Also consider using functools.wraps()
to keep the docstring and name information of the string the same.
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.