Допустим, у нас есть следующие классы:
class Duck(object):
pass
class OldFashionedDuck(Organism, Duck):
def look(self):
self.display_biological_appearance()
def walk(self):
self.keep_balance_on_two_feet()
def quack(self):
self.make_noise_with_lungs("Quack!")
class ArtificialDuck(Robot, Duck):
def look(self):
self.display_imitation_biological_appearance()
def walk(self):
self.engage_leg_clockwork()
def quack(self):
self.play_sound("quack.au")
В этом примере OldFashionedDuck и ArtificialDuck не имеют общей реализации, но по своей конструкции они оба будут возвращать True для isinstance(..., Duck).
Это не идеально, но я подумал, что это может помочь уважать как утиную типизацию, так и (через пустое наследование миксинов) разрешать isinstance(). По сути, он предлагает контракт на соответствие интерфейсу, поэтому на самом деле он вызывает isinstance() не на основе класса, который выполняет всю работу, а на основе интерфейса, на который может подписаться любой.
Я видел статьи, основанные на том, что «isinstance() считается вредным», потому что это нарушает утиную печать. Тем не менее, я, по крайней мере, как программист, хотел бы знать, если не обязательно, откуда объект получает функцию, но реализует ли он интерфейс.
Полезен ли этот подход, и если да, то можно ли его улучшить?
isinstance()
. Это затрудняет решение вопроса о том, правильно ли это делать. - person Marcelo Cantos   schedule 21.01.2013