python—在实例级别和';更新';所有参考资料
我想用类B中的方法重写类A的实例的方法,但要使对实例的旧方法的所有引用(在重写该方法之前进行)都“链接”到新方法。代码:python—在实例级别和';更新';所有参考资料,python,setattr,Python,Setattr,我想用类B中的方法重写类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_somet
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的属性后保存类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)
...
您可以这样做,例如:
...
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.\uu\u name\uu
但是,c.func.\uuuuu name\uuuu
只会使用Alex的方法返回
。我通过创建一个可调用类来防止这种情况,该类使用retain函数,但单独存储方法的名称,在我的例子中,这就足够了,因为它只是一些需要序列化的特定引用
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
只是补充亚历克斯的答案。 在我的例子中,所描述的动态部分来自对序列化和反序列化的需求。为了序列化某些方法引用,我使用
func.\uu\u name\uu
但是,c.func.\uuuuu name\uuuu
只会使用Alex的方法返回
。我通过创建一个可调用类来防止这种情况,该类使用retain函数,但单独存储方法的名称,在我的例子中,这就足够了,因为它只是一些需要序列化的特定引用
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
请注意,
c
必须知道a
,而不仅仅是a.foo
。这是您的设置中可以接受的更改吗?不一定。但在某些情况下,这可能会有所帮助。这取决于实现。请注意,c
必须知道a
,而不仅仅是a.foo
。这是您的设置中可以接受的更改吗?不一定。但在某些情况下,这可能会有所帮助。这要看执行情况。哦,这真的很好!非常感谢你。我会尝试一些东西,但对我来说似乎很可靠。我只是发现了一个小问题。在我的软件中的其他地方,我试图访问引用的序列化方法的名称(c.func.\uuuu name\uuuu
),该方法现在只返回。有什么想法吗?哦,这真是太好了!非常感谢你。我会尝试一些东西,但对我来说似乎很可靠。我只是发现了一个小问题。在我的软件中的其他地方,我试图访问引用的序列化方法的名称(c.func.\uuuu name\uuuu
),该方法现在只返回。有什么想法吗?