Правильно ли говорить, что следующий код реализует полиморфизм в Python3? - PullRequest
4 голосов
/ 19 января 2020

Извините за довольно смутный вопрос. Но я не могу найти строгое определение того, что такое полиморфизм, если мы реализуем его в функции (чтобы эта функция имела общий интерфейс, но принимала объекты разных типов). Например, следующий код действительно реализует полиморфизм? Можем ли мы назвать это так?

class A:
    def func(self):
        pass


class B(A):
    pass


class C(A):
    pass


def common_interface(obj):
    obj.func()


common_interface(B())
common_interface(C())

Ответы [ 2 ]

1 голос
/ 19 января 2020

TLDR: Да, это полиморфизм.


Ваши классы реализуют учебник подтип полиморфизм. Все A, B и C удовлетворяют интерфейсу их общего подтипа A.

Ваша функция реализует структурный полиморфизм (Python называет это Protocol). Он принимает любой тип с атрибутом вызываемого .func.

Хорошо реализованный полиморфизм подтипа также удовлетворяет структурному полиморфизму. Ваша функция принимает B и C не потому, что они удовлетворяют A, а потому, что они имеют атрибут вызываемого .func - что они делают в результате удовлетворения A.


«типирование утки» в Python естественным образом соответствует структурной типизации при использовании объектов. Вы можете форсировать семантику других типов, проверяя типы (например, через isinstance) или используя одну / несколько отправок (например, через singledispatch и аннотации типов.

Для этого примера ваша функция также может использовать полиморфизм подтипа (obj: A) или тип суммы (obj: Union[B, C]).

1 голос
/ 19 января 2020

Компьютерные ученые скажут вам, что существует несколько различных типов полиморфизма. Тип, на который ссылается ваш пример, - это способность ссылки на объект ссылаться на различные типы объектов во время выполнения программы, и когда метод вызывается по этой ссылке, правильная реализация этого метода вызывается на основе фактического текущего типа этого объекта. В Python ссылка на объект - это просто переменная, которой был присвоен объект, например, b в следующем: b = B().

В то время как ваш пример, строго говоря, делает продемонстрировать полиморфизм в том смысле, что вы передаете два объекта разных классов в commmon_interface и можете вызывать метод func для этих двух разных объектов, это не лучший пример, поскольку оба объекта имеют одинаковую точную реализацию этого метод. Следующий пример будет более понятен для студента:

class B():
    def func():
        do_something_1()


class C():
    def func():
        do_something_2()


def foo(obj):
    obj.func()


foo(B())
foo(C())

В методе foo ссылка obj ссылается один раз на объект класса B и один раз на класс C во время выполнения программа. Когда вызывается метод func, будут вызваны две разные реализации . Поэтому, хотя это не является обязательной особенностью полиморфизма, это лучший пример, который описывает его полезность.

В статически типизированных языках, таких как C++ и Java, полиморфизм ограничен publi c наследование. Например, если я объявляю P указателем на объект класса A, то я могу только присвоить P ссылки на объекты класса A или потомков A в иерархии наследования publi c. Но в Python, с указанием утки, такого ограничения нет. Ваш пример может предложить иное.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...