Dynamic ("Duck") Typing¶

The fact that an object's type is determined at run time allows functions to operate on objects of any type that support the methods used by that function.

For example we can define a rectangle type and define the < (less than) operator to compare rectangles based on their areas. This allows us to, for example, sort rectangles according to their areas:

In [1]:
class rect():
    def __init__(self,h,w):
        self.h=h
        self.w=w
    def __lt__(self,x):
        return self.h*self.w < x.h*x.w
    def __repr__(self):
        # return f"rect({str(self.h)},{str(self.w)})"
        return "rect({},{})".format(str(self.h),str(self.w))
    
l=[rect(1,1), rect(2,4), rect(2,2), rect(4,1)]
sorted(l)
Out[1]:
[rect(1,1), rect(2,2), rect(4,1), rect(2,4)]

This is because the sorted() function doesn't need to know the types of the objects it's sorting; it only requires that each object have a __lt__ method.

The term duck typing comes from the saying "if it walks like a duck, swims like a duck and quacks like a duck then it's a duck".

In other words, an object's "type" is determined by the methods that the object implements, not by an explicit declaration.