Duck typing
Python nie sprawdza, z której klasy obiekt odziedziczył, tylko czy ma właściwą metodę.
„Jeśli wygląda jak kaczka i kwacze jak kaczka...”
W sekcji 14.18 wszystkie klasy nie zawsze miały wspólnego rodzica. W rzeczywistości Python w ogóle nie sprawdza, z której klasy obiekt jest dziedziczony, aby wywołać tylko jeśli obiekt MA właściwą metodę:
class Sobaka: # nie ma nic wspólnego z Robot
def predstavitsya(self):
print(„Hau! Jestem psem.”)
class Robot: # nie jest w żaden sposób powiązane z Sobaka
def predstavitsya(self):
print(„BIP. Jestem robotem.”)
def poznakomit(obj):
obj.predstavitsya() # nieważne, jakiej klasy jest obj — ważne, że metoda istnieje
poznakomit(Sobaka())
poznakomit(Robot())
Sobaka oraz Robot NIE mają wspólnego rodzica (poza rodzicem domyślnym) object), ale poznakomit() działa równie dobrze z obiema metodami. W Python interfejs jest faktyczną obecnością pożądanej metody, a nie formalnym wpisem w drzewie dziedziczenia.Nazwa pochodzi od wyrażenia „jeśli wygląda jak kaczka, pływa jak kaczka i kwacze jak kaczka — prawdopodobnie to jest kaczka”: nie ma znaczenia, jak obiekt został stworzony, ważne co POTRAFI.
zhivotnye = [Sobaka(), Robot(), „po prostu łańcuch znaków”]
for zh in zhivotnye:
zh.predstavitsya()
Гав! Я собака.
БИП. Я робот.
Traceback (most recent call last):
AttributeError: 'str' object has no attribute 'predstavitsya'
Duck typing nie sprawdza wcześniej metody — Python po prostu próbuje wywołać predstavitsya() i zawiesza się w momencie wywołania, jeśli metody nie ma. Elastyczność duck typing nie zwalnia z odpowiedzialności: umieszczanie w jednym lista obiektów, które MUSZĄ wspierać wspólną metodę, wymaga świadomego działania.
for zh in zhivotnye:
if hasattr(zh, "predstavitsya"):
zh.predstavitsya()