Module (24%)
Section (70%)

In Python, polymorphism is the provision of a single interface to objects of different types. In other words, it is the ability to create abstract methods from specific types in order to treat those types in a uniform way.

Imagine that you have to print a string or an integer — it is more convenient when a function is called simply print, not print_string or print_integer.

However, the string must be handled differently than the integer, so there will be two implementations of the function that lead to printing, but naming them with a common name creates a convenient abstract interface independent of the type of value to be printed.

The same rule applies to the operation of addition. We know that addition is expressed with the '+' operator, and we can apply that operator when we add two integers or concatenate two strings or two lists.

Let's see what methods are present for both built-in types (string and integer) responsible for handling the '+' operator. Once again, we'll use the dir(object) function, which returns a list of object attributes.

>>> dir(1) ['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__index__', '__init__', '__init_subclass__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes'] >>> dir('a') ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']

output


As you can see, there are many attributes available for the string and integer types, many of them carrying the same names. The first name common to both lists is __add__, which is a special method responsible for handling addition, as you may remember from the previous slides.

To briefly demonstrate polymorphism on integers and strings, execute the following code in the Python interpreter:

a = 10 print(a.__add__(20)) b = 'abc' print(b.__add__('def'))

The result:

30 abcdef

output

By the way, if you look for a method that is used when you print a value associated with an object, the __str__ method is called to prepare a string that is used in turn for printing.