0% found this document useful (0 votes)
32 views

Python Vs C Plus Plus Series - Polymorphism and Duck Typing

Uploaded by

Gabriel Gomes
Copyright
© © All Rights Reserved
Available Formats
Download as PDF or read online on Scribd
0% found this document useful (0 votes)
32 views

Python Vs C Plus Plus Series - Polymorphism and Duck Typing

Uploaded by

Gabriel Gomes
Copyright
© © All Rights Reserved
Available Formats
Download as PDF or read online on Scribd
You are on page 1/ 8
2a/t0/2021 16:59 Pynon vs C+ Series: Polymorphism and Duck Typing - CodaProject Python vs C++ Series: Polymorphism and Duck Typing ‘Shun Huang *) qooct2021 crot Introduce Python's way to support polymorphism and duck typing from the concept of C++ polymorphism ‘This second article of the Python vs. C++ series discusses polymorphism, ‘This isthe second article of the Python vs C++ Series. In this article, we are going to talk about another basic object-oriented programming concept ~ Polymorphism, (Note that the Python code in the series assumes Python 3.7 or newer) Brief Review of Polymorphism Polymorphism is a Greek word that means having many forms. A programming language that supports polymorphism means a variable, a function, or an object can take on multiple forms, such as a function accepting a parameter with different types. Also, vith polymorphism, we can define functions with the same name (ie, the same interface), but the functions have multiple implementations. Polymorphism in C++ C++ supports static (resolved at compile-time) and dynamic (resolved at runtime) polymorphism. Function Overloading In C++, static polymorphism is also known as function overloading, allowing programs to declare multiple functions with the same ame but different parameters. The following shows a sample of function overloading in C++. cet include void myOverloadingFunction(int parameter) // Bo something ? void myOverloadingFunction(std::string parameter) // Bo something ? void myOverloadingFunction(int parametert, std: string paraneter2, float paraneter3) // Do something Iitpsslwwn.codeproject.con/Artcles/5314882/Python-vs-Cplusplus-Series-Polymorphism-and-Duck-T7dlsplay=Print 18 2a/t0/2021 16:59 Pynon vs C+ Series: Polymorphism and Duck Typing - CodaProject Virtual Function and Abstract Class ‘The C++ implements runtime polymorphism is supported by using class hierarchy with virtual functions. When a method in a derived class overrides its base class, the method to call is determined by the object's type at run time. The following code shows how it works in C++ cet #include class BaseClass public: virtual void dolork() // do some work + h class DerivedClassA: public BaseClass { public: virtual void dohork() override // do some work + ub class DerivedClass! € public BaseClass public: virtual void doork() override // do some work us void myFunction(std::shered_ptr p) { // The appropriate doWork() to be called will be determined by // the instance of p at the runtine. pe>doWork(); Interface and Pure Virtual Function When a virtual function appends with = 0, it becomes a pure virtual function, and a class that contains a pure virtual function is called an abstract class, Any class derived from an abstract class must define its pure virtual functions it's supported to be instantiated. Therefore, we usually use an abstract class to define programs’ interfaces. For example: ce class MyInterface { // Since this class contains a pure virtual class; it becomes an abstract // class, and cannot be instantiated. public: // Use a pure virtual function to define an interface. virtual int method(int parameter) = @; class DerivedClass: public MyInterface « public: // If the derived class needs to be instantiated, the derived class // must implement its parent's pure virtual function. hitps:lwwn.codeproject.com/Artcles/5314882/Python-vs-Cplusplus-Series-Polymorphism-and-Duck-T display 28 23/10/2021 16:69 Pynon vs C+ Series: Polymorphism and Duck Typing - CodaProject virtual int method(int parameter) override // do something Duck Typing in Python Duck typing is an application of duck test which says, "Ifit looks like a duck, swims ike a duck, and quacks like a duck, probably is a duck." With duck typing, a function does not check the parameter's type; instead, it checks the presence of the parameter. Duck typing is the essence of dynamic languages lke Python. Function Overloading (One reason we need polymorphism in C++ is that C++ is a static language. Polymorphism allows us to define functions with the same name but take different type parameters or different numbers of parameters. On the contrary, Python is a dynamic language. ‘Therefore, function overloading is not necessary for Python and is not supported (see PEP3142), The following example shows how a Python function deals with a parameter that could be of different types. Python def my_function(paraneter) if type(parameter) is str: print("Oo something when the type is string") elif type(parameter) is int: print("Do something when the type is integer") else: raise Typerror("Invalid type’ if _name_ == "_main_": # Valid my_function(16) y_function(*hello”) # TypeError exception will be thrown my_function(2.3) In this example, my_Funct ion can take any parameter due to the nature of duck typing, Therefore, if we want the function to perform different operations based on the parameter’ type, the function needs to check the presence of the parameter to determine what to do, The output of this example looks lke the following Bash Do something when the type is integer Do something when the type is string Traceback (most recent call last): raise Typetrror("Invalid type") TypeError: Invalid type What will happen if we define multiple functions with the same name? If we define two or more functions with the same name, the Python interpreter will use the last one it scans. For example, the following code will work, but only the last my_Funct ion will be used Python def my_function(paraneter) if type(parameter) is str: print("Oo something when the type is string") hitpsslwwn.codeproject.com/Antcles/531148821Python-vs-Cplusplus-Series-Polymorphism-and-Duck-T7display=Print 38 23/10/2021 16:69 Pynon vs C+ Series: Polymorphism and Duck Typing - CodaProject elif type(parameter) is int: print("Oo something when the type is integer") else: raise Typetrror(“Invalid type") def my_function(paraneter) print(paraneter) if _name__ == "_main, mmy_function(10) my_functiion(2.3) And its output looks like below: Bash 16 2.3 ‘The last my_function (parameter) is the one that is really called, and that's why my_Funct ion(2.3) works Function with Optional Parameters In addition to defining functions with the same name but with different parameter types, with polymorphism, we can also define functions with the same name but take a different number of parameters. Python does not support function overloading, but its keyword arguments and default arguments abilities provide a way to define a function that accepts a different number of parameters, The following code snippet demonstrates the usage of keyword arguments and default arguments, Python def my_function(paraneter1, parameter2=None, paraneter3 print (paraneter1) ‘if paraneter2: print(paraneter2) print(paraneter3) if _name__ == "_main_" # Use default parameter2 and parameter3; parameter 1 does not # have default value, so it cannot be omitted. my_function(10) # Use default paraneter2 my_function(paraneter1=1, paraneter: ) # Use default paraneter3; also notice that the order does not matter # when using keyword arguments. my_function(paraneter2="world", paraneteri=1) ‘The output of my_function(10) Bash 1e hello The output of my_function(parameteri=1, parameter: The output of my_function(parameter2="world”, parameter1=1) hitpsslwwu.codeproject.com/Antcles/53148821Python-vs-Cplusplus-Series-Polymorphism-and-Duck-T7aisplay=Print 48 23/10/2021 16:69 Pynon vs C+ Series: Polymorphism and Duck Typing - CodaProject 1 world hello The Disadvantage When Using Duck Typing With duck typing, Python allows us to write 2 function with different types and a different number of parameters. However, when we need our function to perform certain operations based on the parameters, we will need several i f-e15e statements for each type, and if the 4f-e1Se statement is getting longer, its readability reduces. When this happens, we may need to consider refactoring our code, Python does not have the function overloading benefit that we can leverage function overloading to perform different actions using several small functions as we do in C+ Type Safety and Type Checking Althouigh Python is a dynamic language, it does not mean Python does not care about type safety. Unlike C++ that a compiler will catch most of the type-related errors, Python relies on linting tools to do the job. Starting from Python 35, PEP484 introduces the support of type hints that type checking tools such as mypy can leverage to check Python programs. The following example shows an example of type hints, (More detail of Python's type hints can be found at Support for type hints.) Python from typing import Dict, Optional, Union class MyClass: def my_method_1(self, parameter: int, parameter2: str) -> None pass def my_method_2(self, parameter pass Union[int, str]) -> Dict def my_function(paraneter: Optional [MyClass]): pass Althouigh we can use type hints and linting tools to ensure type safety, the Python runtime does not enforce functions or variables ‘to satisty its type annotations. If we ignore errors or warnings generated by a type checker and stil pass an invalid type parameter, the Python interpreter wll stil execute it. For example, my_Funct ion in the example below expects that parameter is int type and parameter? is string type. However, when the function is called and the type of parameter! is string and the parameter? is float, the Python interpreter wil execute it Python ef my_function(paraneteri: int, paraneter2: print(f"Parameter 1: {paraneter1} print(#"Parameter 2: {parameter2} str) -> None: if _name__ == "_main_": my_function(paraneterd "Hello", parameter: 5) If we run 3 type checker (using mypy in the example), it will show incompatible type errors. (Use MYPY as an example.) Python $ mypy python_type_hints_2.py python_type_hints_2.py:12: error: Argument. “parameter: "str"; expected “int python_type_hints_2.py:12: error: Argument “parameter2" to “ny_function" has incompatible type to “my_function" has incompatible type hitpsslww.codeproject.com/Antcles/53114882/Python-vs-Cplusplus-Series-Polymorphism-and-Duck-T7aisplay=Print 58 23/10/2021 16:69 Pynon vs C+ Series: Polymorphism and Duck Typing - CodaProject oat"; expected Found 2'errors in 1 file (checked 1 source file) work However, if we execute the code, it will st Python $ python python_type_hints_2.py Parameter 1: Hello Paraneter 2: 3.5 Python type hints are only for linting tools to check types but have no effect on runtime, Abstract Base Class and Interface Python does not have the concept of virtual function or interface like C++, However, Python provides an infrastructure that allows Us to build something resembling interfaces’ functionality ~ Abstract Base Classes (ABO) ‘ABC is a class that does not need to provide a concrete implementation but is used for two purposes: 1. Check for implicit interface compatibilly, ABC defines a blueprint of a class that may be used to check against type compatibility. The concept is similar to the concept of abstract classes and virtual functions in C+ 2. Check for implementation completeness, ABC defines a set of methods and properties that a derived class must implement. In the following example, BasicBinaryTree defines the interface for binary trees. Any derived binary tree (eg, an AVL tree or a Binary Search Tree) must implement the methods defined in the BasicBinaryTree. To use ABC to define an interface, the interface class needs to inherit from the helper class ~ abc ABC. The method that the derived classes must implement uses @abc abstractmethod decorator (equivalent to pure virtual functions in C++) Python class BasicBinaryTree(abc.ABC): Gabe. abstractmethod def insert(self, key: int) -> None: raise NotImplementedError() Gabe. abstractmethod def delete(self, key: int) -> None: raise NotImplementedError() @abc.abstractmethod def search(self, key: int) -> Node: raise NotImplementederror() ‘The derived class (use AVLTrree as an example) inherits the abstract base class (ie, BasicBinaryTree in this example) and implements the methods defined with the @abc.obstactmethod decorator. Python class AVLTree(BasicBinaryTree) : """AVL Tree implementation. def insert(self, key: int) -> None: # The AVL Tree implementation pass def delete(self, key: int) -> None: # The AVL Tree implementation pass def search(self, key: int) -> AVLNode: # The AVL Tree implementation pass hitps:slwwu.codeproject.com/Antcles/53114882/Python-vs-Cplusplus-Series-Polymorphism-and-Duck-T7aisplay=Print 38 23/10/2021 16:69 Pynon vs C+ Series: Polymorphism and Duck Typing - CodaProject ‘The complete example of the binary tree interface is the following (also available at python interface.py). Python import abe from typing import Optional from dataclasses inport dataclass @dataclass class Node: "Basic binary tree node definition. key: int left: Optional{“Node"] = None right: Optional["Node"] = None parent: Optional "Node"] = None class BasicBinaryTree(abc.ABC) : "ean abstract base class defines the interface for any type of binary trees. The derived class should implement the abstract method defined in the abstract e class. Gabe. abstractmethod def insert(self, key: int) -> None: raise NotImplementedError() @abe.abstractmethod def delete(self, key: int) -> None: raise NotImplementedError() Gabe. abstractmethod def search(self, key: int) -> Node: raise NotImplementedError() class BinarySearchTree(BasicBinaryTree) : Binary Search Tree. def insert(self, key: int) -> None: # The BST impLenentation pass def delete(self, key: int) -> None: # The BST inpLenentation pass def search(self, key: int) -> Node: # The BST impLenentation pass @dataclass class AVLNode (Node) ‘AVL Tree node definition. Derived from Node." left: Optional "AVLNode"] = None right: Optional ["AVLNode"] = None parent: Optional ["AVLNode”] = None height: int = @ class AVLTree(BasicBinaryTree’ ‘AVL Tree implementation. def insert(self, key: int) -> None: # The AVL Tree implementation pass def delete(self, key: int) -> None: hitps:slww.codeproject.com/Antcles/53148821Python-vs-Cplusplus-Series-Polymorphism-and-Duck-T7aisplay=Print 78 2a/t0/2021 16:59 Pynon vs C+ Series: Polymorphism and Duck Typing - CodaProject # The AVL Tree implementation pass def search(self, key: int) -> AVLNode: # The AVL Tree implementation pass Conclusion Python may support polymorphism differently from C++, but the concept of polymorphism is still valid and widely used in Python programs, and the importance of type safety is still essential to Python programs. License This article, along with any associated source code and file, is licensed under The Code Project Open License (CPOL) About the Author Shun Huang Software Developer (Senior) United States My name is Shun. lam a software engineer and a Cristian. currently work at a startup company. My Website: htpsi//shunsvineyard.info Email: [email protected] Comments and Discussions (514 messages have been posted for this article Vist https://www.cadeproject.com/Articles/5314882/Python-vs-Cplusplus- ‘Series-Polymorphism-and-Duck-T to post and view comments on this article, or click here to get a print view with messages. Permalink Article Copyright 2021 by Shun Huang Advertise Everything else Copyright © CodeProject, 1999- Privacy 2021 Cookies Terms of Use Webod 28 20211019.1 Iitps:slwwn.codeproject.con/Artcles/5314882/Python-vs-Cplusplus-Series-Polymorphism-and-Duck-T7dlsplay=Print oo

You might also like