What is Duck Typing in Python Oops? Advantages, Disadvantages, and Use Cases

Estimated read time: 6 min

Python is a dynamically typed language, which means it doesn't require explicit declaration of variable types. One of the key principles that embodies this flexibility is Duck Typing. This blog explores duck typing in Python, its practical applications, and its pros and cons.

What is Duck Typing?

Duck typing is a programming paradigm where an object's suitability for use is determined by the presence of certain methods and properties, rather than its explicit inheritance from a specific class. This is different from traditional object-oriented programming (OOP), where you check an object's type to ensure it has the correct class or interface.

In Python, an object is considered valid if it has the methods and attributes you're looking for. The core idea is: “If it quacks like a duck and swims like a duck, it's a duck.”

Code Walkthrough: Food Type Example

Let’s dive into a simple example that demonstrates the concept of duck typing in Python.

  • Defining the Food Classes

We begin by defining four different food categories: FruitsGrainsVegetables, and FastFood. Each of these classes implements a few common methods: food_typeis_organiccalories_per_100g, and common_cooking_methods.


class Fruits:
    def food_type(self):
        return 'Food type is fruits'

    def is_organic(self):
        return True

    def calories_per_100g(self):
        return 52  # Example value for fruits like apples

    def common_cooking_methods(self):
        return ['Eat raw', 'Make smoothies', 'Use in desserts']

class Grains:
    def food_type(self):
        return 'Food type is grains'
   
    def is_organic(self):
        return True

    def calories_per_100g(self):
        return 365  # Example value for grains like rice

    def common_cooking_methods(self):
        return ['Boil', 'Fry', 'Use in soups or salads']

class Vegetables:
    def food_type(self):
        return 'Food type is vegetables'

    def is_organic(self):
        return True

    def calories_per_100g(self):
        return 35  # Example value for vegetables like spinach

    def common_cooking_methods(self):
        return ['Steam', 'Boil', 'Saute', 'Roast']

class FastFood:
    def food_type(self):
        return 'Food type is fast food'

    def is_organic(self):
        return False

    def calories_per_100g(self):
        return 250  # Example value for fast food items like burgers

    def common_cooking_methods(self):
        return ['Fry', 'Grill', 'Bake']

  • Call method using class object (Not Batter way)

# Objects of class
a = Fruits()
b = Vegetables()
c = FastFood()

print(a.food_type())
print(a.calories_per_100g())
print(a.common_cooking_methods())
# Food type is fruits
# 52
# ['Eat raw', 'Make smoothies', 'Use in desserts']

print(b.food_type())
print(b.calories_per_100g())
print(b.common_cooking_methods())
# Food type is vegetables
# 35
# ['Steam', 'Boil', 'Saute', 'Roast']

print(c.food_type())
print(c.calories_per_100g())
print(c.common_cooking_methods())
# Food type is fast food
# 250
# ['Fry', 'Grill', 'Bake']

  • Call method using handler with duck-tying fashion (Batter way)


# Objects of class
a = Fruits()
b = Vegetables()
c = FastFood()

# Object handler
def food_type_handler(obj):

    return obj.food_type()

def calory_handler(obj):

    return obj.calories_per_100g()

def cooking_handler(obj):

    return obj.common_cooking_methods()

# Using the handler functions on different objects
print(food_type_handler(a))  
# Output: "Food type is fruits"
print(calory_handler(a))  
# Output: 52
print(cooking_handler(a))  
# Output: ['Eat raw', 'Make smoothies', 'Use in desserts']

print(food_type_handler(b))  
# Output: "Food type is vegetables"
print(calory_handler(b))  
# Output: 35
print(cooking_handler(b))  
# Output: ['Steam', 'Boil', 'Saute', 'Roast']

print(food_type_handler(c))  
# Output: "Food type is fast food"
print(calory_handler(c))  
# Output: 250
print(cooking_handler(c))  
# Output: ['Fry', 'Grill', 'Bake']


Explanation of the Code
  1. Class Definitions:
    • We define four classes: FruitsGrainsVegetables, and FastFood. Each class has the following methods:
      • food_type(): Returns a string indicating the type of food.
      • is_organic(): Returns whether the food is organic or not.
      • calories_per_100g(): Returns the caloric value per 100g.
      • common_cooking_methods(): Returns a list of common ways to cook or consume the food.
  2. Objects Creation:
    • We create objects of FruitsVegetables, and FastFood. These objects are passed into handler functions that call the appropriate methods dynamically, demonstrating Duck Typing.
  3. Handler Functions:
    • food_type_handler(): This function takes an object and returns its food type by calling food_type().
    • calory_handler(): This function takes an object and returns its caloric value per 100g by calling calories_per_100g().
    • cooking_handler(): This function takes an object and returns a list of common cooking methods by calling common_cooking_methods().

Advantages of Duck Typing

  • Flexibility: Duck typing allows for more flexible code because you don’t have to worry about explicit type declarations. You can pass objects of different classes, as long as they implement the expected methods.
  • Code Reusability: Since duck typing doesn’t require specific types, you can reuse functions across different types of objects that implement the same methods, promoting cleaner, more concise code.
  • Ease of Refactoring: Duck typing makes it easier to refactor code. You can change the underlying class of an object without worrying about updating all the places where that object is used, as long as the new class implements the necessary methods.

Disadvantages of Duck Typing

  • Potential for Runtime Errors: Since Python doesn’t enforce strict type checking, it’s possible to call a method on an object that doesn’t exist, leading to runtime errors. This can make debugging more difficult.
  • Reduced Readability: For developers unfamiliar with duck typing, it might be harder to understand what kind of objects are being passed to functions. This can lead to confusion, especially in larger projects.
  • Lack of Explicit Interfaces: Duck typing relies on convention rather than enforcement, meaning that there is no explicit contract for what methods a class should have. This can sometimes lead to unclear expectations for object behavior.

Conclusion

Duck typing in Python is a powerful concept that allows for more dynamic and flexible code. By focusing on what methods an object supports rather than its specific class or type, we can write more reusable and clean code. However, it also comes with some risks, such as potential runtime errors and reduced readability.

In this blog, we explored how duck typing works with a food-related example, demonstrating how you can pass various food objects to the same function without worrying about their class type. Duck typing allows Python developers to write code that is both flexible and extensible, making it a valuable tool in object-oriented programming.

💫Thank you💫

Post a Comment

Cookie Consent
We serve cookies on this site to analyze traffic, remember your preferences, and optimize your experience.
Oops!
It seems there is something wrong with your internet connection. Please connect to the internet and start browsing again.
AdBlock Detected!
We have detected that you are using adblocking plugin in your browser.
The revenue we earn by the advertisements is used to manage this website, we request you to whitelist our website in your adblocking plugin.
Site is Blocked
Sorry! This site is not available in your country.