Duck Typing
Python, Polymorphism allows us to use a single interface (like a function or a method) for objects of different types. Duck Typing is a specific style of polymorphism common in dynamically-typed languages like Python.
What is Duck Typing? 🦆
The name comes from the saying:
“If it walks like a duck and it quacks like a duck, then it must be a duck.”
In programming terms, this means that instead of checking an object’s type to see if it has the right methods, Python simply tries to execute the methods. If the object has the methods we need (if it “quacks”), Python will run the code. If it doesn’t, it will raise an error at runtime.
The focus is on the object’s behavior (what it can do) rather than its type (what class it is).
Example
Let’s imagine we have several different classes, none of which are related by inheritance. However, they all have a method with the same name, speak().
Python
# 1. Define different classes with the same method name
class Dog:
def speak(self):
return "Woof! 🐶"
class Cat:
def speak(self):
return "Meow! 🐱"
class Duck:
def speak(self):
return "Quack! 🦆"
class Human:
def talk(self): # Note this method has a different name
return "Hello! 👋"
# 2. Create a function that can work with any object that has a 'speak' method
def make_it_speak(creature):
"""
This function doesn't care about the type of 'creature'.
It only cares that the 'creature' object has a .speak() method.
"""
print(creature.speak())
# 3. Create instances of our classes
dog = Dog()
cat = Cat()
duck = Duck()
person = Human()
# 4. Call the function with different types of objects
print("Calling make_it_speak() with different objects:")
make_it_speak(dog) # Works because Dog has a .speak() method
make_it_speak(cat) # Works because Cat has a .speak() method
make_it_speak(duck) # Works because Duck has a .speak() method
# What happens if we pass an object that can't "speak"?
try:
print("\nTrying to call make_it_speak() with a Human object:")
make_it_speak(person)
except AttributeError as e:
print(f"Error: {e}")
Output:
Calling make_it_speak() with different objects:
Woof! 🐶
Meow! 🐱
Quack! 🦆
Trying to call make_it_speak() with a Human object:
Error: 'Human' object has no attribute 'speak'
Explanation of the Example
- Multiple Classes: We have
Dog,Cat, andDuckclasses. They are completely independent of each other. - Shared Behavior: They all implement a method called
speak(). - Polymorphic Function: The
make_it_speak()function takes any object and calls its.speak()method. It doesn’t perform any type-checking likeif isinstance(creature, Dog):. It just assumes the object canspeak(). - Successful Calls: When we pass instances of
Dog,Cat, andDuck, the function works perfectly because those objects have the required behavior (the.speak()method). - Runtime Error: When we pass the
Humanobject, the program fails with anAttributeError. This is because theHumanobject does not have a.speak()method; it has.talk()instead. The error happens at the moment Python tries to execute.speak(), not before.
This flexibility is a core strength of Python, allowing you to write more generic and reusable code that isn’t tied to specific class hierarchies.
పైథాన్లో పాలిమార్ఫిజం (డక్ టైపింగ్) గురించిన వివరణను తెలుగులో కింద ఇచ్చాను.
డక్ టైపింగ్ అంటే ఏమిటి? 🦆
ఈ పేరు ఒక సామెత నుండి వచ్చింది:
“ఒకవేళ అది బాతులా నడిచి, బాతులా అరిస్తే, అప్పుడు అది బాతు అయి ఉండాలి.”
ప్రోగ్రామింగ్ పరంగా దీని అర్థం, ఒక ఆబ్జెక్ట్కు సరైన మెథడ్స్ ఉన్నాయో లేదో చూడటానికి దాని రకాన్ని (type) తనిఖీ చేయడానికి బదులుగా, పైథాన్ కేవలం ఆ మెథడ్స్ను ప్రయత్నించి చూస్తుంది. ఒకవేళ ఆబ్జెక్ట్కు మనకు అవసరమైన మెథడ్స్ ఉంటే (అది “బాతులా అరిస్తే”), పైథాన్ కోడ్ను రన్ చేస్తుంది. లేకపోతే, రన్టైమ్లో ఎర్రర్ వస్తుంది.
ఇక్కడ ఆబ్జెక్ట్ యొక్క రకం (అది ఏ క్లాస్కు చెందినది) కంటే దాని ప్రవర్తనపై (అది ఏమి చేయగలదు) ఎక్కువ దృష్టి ఉంటుంది.
ఉదాహరణ
వివిధ క్లాస్లను ఊహించుకుందాం, వాటి మధ్య వారసత్వ సంబంధం (inheritance) ఏదీ లేదు. కానీ, వాటన్నింటికీ ఒకే పేరుతో speak() అనే మెథడ్ ఉంది.
Python
# 1. ఒకే మెథడ్ పేరుతో వేర్వేరు క్లాస్లను డిఫైన్ చేయడం
class Dog:
def speak(self):
return "భౌ! భౌ! 🐶"
class Cat:
def speak(self):
return "మ్యావ్! 🐱"
class Duck:
def speak(self):
return "క్వాక్! క్వాక్! 🦆"
class Human:
def talk(self): # గమనిక: ఈ మెథడ్ పేరు భిన్నంగా ఉంది
return "నమస్కారం! 👋"
# 2. 'speak' మెథడ్ ఉన్న ఏ ఆబ్జెక్ట్తోనైనా పనిచేసే ఫంక్షన్ను క్రియేట్ చేయడం
def make_it_speak(creature):
"""
ఈ ఫంక్షన్ 'creature' యొక్క రకం గురించి పట్టించుకోదు.
'creature' ఆబ్జెక్ట్కు .speak() మెథడ్ ఉందా లేదా అనేదే దీనికి ముఖ్యం.
"""
print(creature.speak())
# 3. మన క్లాస్ల యొక్క ఇన్స్టాన్స్లను క్రియేట్ చేయడం
dog = Dog()
cat = Cat()
duck = Duck()
person = Human()
# 4. వేర్వేరు రకాల ఆబ్జెక్ట్లతో ఫంక్షన్ను కాల్ చేయడం
print("వివిధ ఆబ్జెక్ట్లతో make_it_speak() ను కాల్ చేస్తున్నాం:")
make_it_speak(dog) # Dog కు .speak() మెథడ్ ఉన్నందున పనిచేస్తుంది
make_it_speak(cat) # Cat కు .speak() మెథడ్ ఉన్నందున పనిచేస్తుంది
make_it_speak(duck) # Duck కు .speak() మెథడ్ ఉన్నందున పనిచేస్తుంది
# "speak" చేయలేని ఆబ్జెక్ట్ను పాస్ చేస్తే ఏమవుతుంది?
try:
print("\nHuman ఆబ్జెక్ట్తో make_it_speak() ను కాల్ చేయడానికి ప్రయత్నిస్తున్నాం:")
make_it_speak(person)
except AttributeError as e:
print(f"లోపం (Error): {e}")
ఫలితం (Output):
వివిధ ఆబ్జెక్ట్లతో make_it_speak() ను కాల్ చేస్తున్నాం:
భౌ! భౌ! 🐶
మ్యావ్! 🐱
క్వాక్! క్వాక్! 🦆
Human ఆబ్జెక్ట్తో make_it_speak() ను కాల్ చేయడానికి ప్రయత్నిస్తున్నాం:
లోపం (Error): 'Human' object has no attribute 'speak'
ఉదాహరణ యొక్క వివరణ
- వివిధ క్లాస్లు: మనకు
Dog,Cat, మరియుDuckక్లాస్లు ఉన్నాయి. అవి ఒకదానికొకటి పూర్తిగా స్వతంత్రంగా ఉన్నాయి. - ఉమ్మడి ప్రవర్తన: అవన్నీ
speak()అనే మెథడ్ను కలిగి ఉన్నాయి. - పాలిమార్ఫిక్ ఫంక్షన్:
make_it_speak()ఫంక్షన్ ఏ ఆబ్జెక్ట్ను అయినా తీసుకుని దాని.speak()మెథడ్ను కాల్ చేస్తుంది. ఇది ఏ రకమైన టైప్-చెకింగ్ చేయదు. ఇది కేవలం ఆబ్జెక్ట్speak()చేయగలదని ఊహిస్తుంది. - విజయవంతమైన కాల్స్: మనం
Dog,Cat, మరియుDuckఇన్స్టాన్స్లను పాస్ చేసినప్పుడు, ఫంక్షన్ సరిగ్గా పనిచేస్తుంది ఎందుకంటే ఆ ఆబ్జెక్ట్లకు అవసరమైన ప్రవర్తన (.speak()మెథడ్) ఉంది. - రన్టైమ్ లోపం: మనం
Humanఆబ్జెక్ట్ను పాస్ చేసినప్పుడు, ప్రోగ్రామ్AttributeErrorతో విఫలమవుతుంది. ఎందుకంటేHumanఆబ్జెక్ట్కు.speak()మెథడ్ లేదు; దానికి బదులుగా.talk()ఉంది. పైథాన్.speak()ను ఎగ్జిక్యూట్ చేయడానికి ప్రయత్నించిన క్షణంలో ఈ లోపం సంభవిస్తుంది, అంతకు ముందు కాదు.
ఈ సౌలభ్యం పైథాన్ యొక్క ముఖ్యమైన బలం, ఇది నిర్దిష్ట క్లాస్ నిర్మాణాలకు కట్టుబడి ఉండకుండా, మరింత సాధారణమైన మరియు పునర్వినియోగపరచదగిన కోడ్ను వ్రాయడానికి మిమ్మల్ని అనుమతిస్తుంది.