ProgrammingPython Developer

What is the essence of duck typing in Python? How does it influence code design and maintenance, and what pitfalls are hidden in it?

Pass interviews with Hintsage AI assistant

Answer.

Duck typing is a fundamental principle of Python, where an object is evaluated based on its behavior rather than its class hierarchy.

Background

The term comes from the saying: "If it looks like a duck, swims like a duck, and quacks like a duck, then it probably is a duck." In Python, the behavior of an object (its interface) is more important than the class to which it belongs. This implements the principle of "duck typing" — behavior-based typing (structural typing).

Problem

It seems that duck typing offers maximum flexibility. However, this increases the number of hidden bugs: the program "breaks" only during runtime if an object does not support the required interface.

Solution

Instead of checking the type (using isinstance or type), write functions that attempt to call the required methods on the object, assuming that if it supports them, everything will work. In extreme cases, catch AttributeError or TypeError to handle unexpected objects.

Example:

def quack_and_walk(duck): duck.quack() duck.walk() class Robot: def quack(self): print("I can quack!") def walk(self): print("I am walking") quack_and_walk(Robot()) # everything will work!

Key features:

  • The behavior of an object is more important than its class.
  • The ability to use external code with completely new types if the required methods are implemented, without inheritance.
  • Downside: errors due to a missing method only manifest during execution.

Trick Questions.

Is it possible to check the type in Python using isinstance and say that this is correct for duck typing?

No. Duck typing is precisely opposed to strict type checking. It is more correct to operate with the behavior of the object rather than its lineage.

Can duck typing be implemented using abstract base classes (ABC)?

Partially. Abstract classes introduce elements of static structure. Duck typing does not require declaring relationships — you simply need to implement the required methods. But with Python 3.8, the typing.Protocol module was introduced, which brings us closer to structural typing.

Can duck typing work with magical methods (len, getitem etc.)?

Yes. If an object implements the required method (len), it can be passed to functions like len(obj), and this will work using duck typing.

Common Mistakes and Anti-Patterns

  • Relying on class-based checks (isinstance) instead of behavior.
  • Not handling exceptions that may arise from a missing method.
  • Using duck typing where explicit type guarantees are needed (for example, in critical libraries).

Real-Life Example

Negative Case

A developer writes a function that accepts anything with a run() method, without checking. An object without this method appears in the code — and the error occurs only at runtime.

Pros:

  • Flexibility, fast prototyping.

Cons:

  • Hard to debug, high cost of error (the program crashes where you do not expect).

Positive Case

Using duck typing but with try/except and interface documentation:

def run_task(obj): try: obj.run() except AttributeError: print("The object does not support running a task!")

Pros:

  • Flexibility, support for multiple types.
  • Controlled failure points.

Cons:

  • Still no hard contracts, additional documentation is needed.