Python Glossary English

все Python 3ООПпонятие

Полиморфизм

полиморфизм

Один интерфейс — разные реализации. В Python достигается переопределением методов и duck typing.

Синтаксис

for obj in objects:
    obj.method()  # разные реализации

В Python объектам не обязательно иметь общего предка — хватает совпадающих имён методов (duck typing), поэтому полиморфизм работает и вовсе без наследования. Базовый класс с NotImplementedError — только соглашение; чтобы отсутствие метода ловилось при создании объекта, а не при его вызове, используйте abc.ABC с @abstractmethod.

Примеры

class Shape:
    def area(self):
        raise NotImplementedError
class Circle(Shape):
    def __init__(self, r):
        self.r = r
    def area(self):
        import math
        return math.pi * self.r**2
class Rectangle(Shape):
    def __init__(self, w, h):
        self.w = w; self.h = h
    def area(self):
        return self.w * self.h
shapes = [Circle(3), Rectangle(4,5)]
for s in shapes:
    print(round(s.area(), 2))  # → 28.27 / 20
# Duck typing
class Dog:
    def speak(self):
        return 'Woof!'
class Cat:
    def speak(self):
        return 'Meow!'
class Duck:
    def speak(self):
        return 'Quack!'
for animal in [Dog(), Cat(), Duck()]:
    print(animal.speak())  # → Woof! Meow! Quack!
# Общая функция — полиморфный вызов
def make_sound(animal):
    print(animal.speak())
make_sound(Dog())   # → Woof!
make_sound(Duck())  # → Quack!
# Перегрузка операторов — полиморфизм
class Vector:
    def __init__(self, x):
        self.x = x
    def __add__(self, other):
        return Vector(self.x + other.x)
class Matrix:
    def __init__(self, data):
        self.data = data
    def __add__(self, other):
        return Matrix([[a + b for a, b in zip(r1, r2)]
                       for r1, r2 in zip(self.data, other.data)])
print((Vector(1)+Vector(2)).x)  # → 3
# isinstance + полиморфизм
def describe(obj):
    if isinstance(obj, list):
        return f'list of {len(obj)}'
    elif isinstance(obj, str):
        return f'string: {obj!r}'
    else:
        return f'other: {type(obj).__name__}'
print(describe([1,2,3]))  # → list of 3
print(describe('hi'))     # → string: 'hi'

См. также

Открыть в полном глоссарииdocs.python.orgСообщить о неточности