В вашем коде сначала выполняется a.foo = b.foo
, где a
был объектом, созданным в b = C()
, а b был объектом, созданным в B()
. Затем при следующем запуске a.foo()
запускается B foo(self)
, где self
- это B()
объект. Там он запускает transform(self, C())
, где self
- это все еще объект, созданный с B()
, , а не объектом на b
. По сути, b
изменяется только один раз, затем никогда не изменяется снова.
Вместо этого вы должны получить несвязанный функциональный объект foo
с помощью b.foo.__func__
, прежде чем назначить его другому, или self
в foo
будет ссылаться на объект B()
вместо b
. Затем вы можете привязать его к целевому объекту с помощью types.MethodType
:
from types import MethodType
def transform(a, b):
a.foo = MethodType(b.foo.__func__, a)
class A:
def foo(self):
pass
class B(A):
def foo(self):
print("bar")
transform(self, C())
class C(A):
def foo(self):
print("foo")
transform(self, B())
b = C()
b.foo()
b.foo()
b.foo()
b.foo()
foo
bar
foo
bar
Ваша вторая попытка также исправлена, выполнив то же самое:
from types import MethodType
class A:
def foo(self):
pass
def transform(self, to):
self.foo = MethodType(to.foo.__func__, self)
class B(A):
def foo(self):
print("bar")
self.transform(C())
class C(A):
def foo(self):
print("foo")
self.transform(B())
b = C()
b.foo()
b.foo()
b.foo()
b.foo()
foo
bar
foo
bar