Заменить метод методом экземпляра другого класса - PullRequest
0 голосов
/ 08 ноября 2019

Я только что попытался создать систему с некоторыми классами со схожим родительским классом, которая динамически назначает их метод между ними. Это похоже на одну функцию "transform (from, to)", которая выполняет что-то вроде from.foo = to. foo

Итак, вы видите, что у меня проблема с Python, поэтому я прошу помощи

Моя первая попытка была

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()

Я хочу получитьот этого что-то вроде

foo
bar
foo
bar

Но я получаю

foo
bar
bar
bar

Самый смешной момент из всех - это то, что первое преобразование работает, но затем.


Мой следующийпопытка была

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()

и я получил тот же результат. У вас есть идеи, как управлять этим преобразованием?

1 Ответ

1 голос
/ 08 ноября 2019

В вашем коде сначала выполняется 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...