в следующем коде я использую интерфейсы для фигур Rect и Circle. В результате я могу в методе calc класса AreaCalc при помощи условного оператора проверить имеет ли проверяемая форма нужный метод.
#!/usr/bin/env python3 from abc import ABCMeta, abstractmethod class Shape_(metaclass=ABCMeta): @abstractmethod def calc_(self): pass class Shape(metaclass=ABCMeta): @abstractmethod def calc(self): pass class Rect(Shape): def __init__(self, w, h): self.w = w self.h = h def calc(self): area = self.w * self.h print('area rect:', area) class Circle(Shape): def __init__(self, r): self.r = r def calc(self): area = self.r * self.r * 3.14 print('area circle: ', area) class AreaCalc: def calc(self, shape): # if isinstance(shape, Shape_): # wrong if isinstance(shape, Shape): # right shape.calc() else: raise Exception('wrong interface') circle = Circle(2) rect = Rect(4, 2) areaCalc = AreaCalc() areaCalc.calc(rect) areaCalc.calc(circle)
LIVE DEMO
но этого условия могло бы и не быть. его появление обусловлено только аккуратностью программиста.
в строготипизированных языках, таких как java или typescript я мог бы обойтись без условного оператора, а просто указать тип принимаемого параметра так:
class AreaCalc() {
calc(shape: Shape) {
shape.calc()
}
}таким образом когда я вижу, например, описание какого-нибудь классического паттерна из GoF и т.п., то я понимаю, что в случае с python есть возможность не усложнять код интерфейсами, а написать без них(хотя аккуратнее было бы с ними)