[英]python - dynamically overriding a method at instance level and 'updating' all references
我想用 class B 中的方法覆盖 class A 实例的方法,但在某种程度上,所有对实例旧方法的引用(在覆盖方法之前进行)然后“链接”到新方法。 在代码中:
import types
class A:
def foo(self):
print('A')
class B:
def foo(self):
print('B')
class C:
def __init__(self, a):
self.func = a.foo
def do_something(self):
self.func()
a = A()
c = C(a)
method_name = 'foo' # it has to be dynamic
new_method = getattr(B, method_name)
setattr(a, method_name, types.MethodType(new_method, a))
c.do_something() # still prints A, I want it to print B now
我希望c.func
在设置 a 的属性后保存来自 class B 的新方法(不对 c 对象执行任何操作)。
有没有办法设置实例 a 的属性,以便所有先前进行的引用然后引用新方法?
抱歉,如果这个问题有点愚蠢,我对此并不感兴趣。
你可以这样做,例如:
...
def retain(foo):
return lambda *args, **kwargs: getattr(foo.__self__, foo.__name__)(*args, **kwargs)
class C:
def __init__(self, a):
self.func = retain(a.foo)
...
只是添加到亚历克斯的答案。 就我而言,所描述的动态部分来自对序列化和反序列化的需要。 为了序列化某些方法引用,我曾经使用func.__name__
。
但是, c.func.__name__
只会使用 Alex 的方法返回<lambda>
。 我通过创建一个可调用的 class 来防止这种情况,该 class 使用保留 function 但单独存储方法的名称,这在我的情况下就足够了,因为它只是我需要序列化的一些特定引用。
def retain(foo):
return lambda *args, **kwargs: getattr(foo.__self__, foo.__name__)(*args, **kwargs)
class M:
def __init__(self, method):
self.method_name = method.__name__
self.method = retain(method)
def __call__(self, *args, **kwargs):
self.method(*args, **kwargs)
class A:
def foo(self):
print('A')
class B:
def foo(self):
print('B')
class C:
def __init__(self, method):
self.func = M(method)
def do_something(self):
self.func()
a = A()
c = C(a.foo)
setattr(a, method_name, types.MethodType(getattr(B, 'foo'), a))
c.do_something() # now prints B
# when serializing
method_name = c.func.method_name
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.