Reputation: 11
I just tried to make a system with some classes with similar parent class, which dynamically assigns their method between them, It looks like one function "transform(from, to)", which doing smth like from.foo = to.foo
So, you see, that my problem is difficult with Python, so I'm asking for help
My first try was
def transform(a, b):
a.foo = b.foo
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()
I want to get from it smth like
foo
bar
foo
bar
But I get
foo
bar
bar
bar
The funniest moment of all is that first conversion working, but next.
My next try was
class A:
def foo(self):
pass
def transform(self, to):
self.foo = to.foo
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()
and I got the same result. Do you have any idea how to manage this conversion?
Upvotes: 0
Views: 49
Reputation: 20269
In your code, it first runs a.foo = b.foo
, where a
was the object created at b = C()
, and b was the object created at B()
. Then when a.foo()
is next run, it runs B's foo(self)
where self
is that B()
object. There, it runs transform(self, C())
where self
is still the object created with B()
, not the object at b
. Basically, b
is only modified once then never modified again.
Instead, you should get the unbound function object of foo
with b.foo.__func__
before assigning it to the other one, or the self
in foo
will refer to the object B()
instead of b
. Then, you can bind it back to the destination object with 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
Your 2nd attempt is also fixed by doing the same thing:
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
Upvotes: 1