Принимая метод класса Python как функцию polymorphi c - PullRequest
1 голос
/ 05 августа 2020

Edit: этот вопрос основан на двух ошибках: изначально не было включено self в методы и предполагалось, что неограниченные методы не будут демонстрировать полиморфизм, но они есть. Я проголосовал за его закрытие.

Я могу использовать метод как объект со значением функции в Python:

class A:
    def foo(self):
        return "Hi, I'm A.foo"

f = A.foo
a = A()
print(f(a))

производит Hi, I'm A.foo.

Пока так хорошо. Однако f не будет работать для подклассов:

class B(A):
    def foo(self):
        return "Hi, I'm B.foo"

f = A.foo
b = B()
f(b)

по-прежнему производит Hi, I'm A.foo, тогда как b.foo() дает Hi, I'm B.foo. Другими словами, полиморфизм не применяется.

Вопрос: есть ли способ получить объект со значением функции в f, чтобы f(x) == x.foo() всякий раз, когда isinstance(x, A)?

В другом слова, как мне заполнить приведенный ниже фрагмент, чтобы все работало?

class A:
    def foo(self):
        return "Hi, I'm A.foo"

class B(A):
    def foo(self):
        return "Hi, I'm B.foo"

f = <WHAT DO I PUT HERE?>
a = A()
b = B()
assert f(a) == a.foo()
assert f(b) == b.foo()

1 Ответ

1 голос
/ 05 августа 2020

Вы можете вывести имя класса следующим образом:

class A:
    def foo(self):
        return "Hi, I'm {}.foo".format(self.__class__.__name__)

class B(A):
    def foo(self):
        return "Hi, I'm {}.foo".format(self.__class__.__name__)

f = A.foo  # this could be A or B, doesn't matter
a = A()
b = B()
assert f(a) == a.foo()
assert f(b) == b.foo()

Обратите внимание, что, поскольку B наследуется от A, вам даже не нужен метод foo:

class A:
    def foo(self):
        return "Hi, I'm {}.foo".format(self.__class__.__name__)

class B(A):
    pass

f = A.foo
a = A()
b = B()
assert f(a) == a.foo()
assert f(b) == b.foo()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...