Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Virtual function being implemented without any initialization in python

Consider the following code :

class parent_print():
    
    def print_word(self):
        self.print_hello()
        
class child_print(parent_print):
    
    def print_hello(self):
        print('Hello')
        
        
basic_print = child_print()
basic_print.print_word()

Here I am assuming that print_hello() is a virtual function in the parent class. And all the children of parent (parent_print) will have a method implemented named print_hello. So that all children can call a single function print_word and appropriate binding to the print_hello function is done based on the child’s method implementation.

But in languages like C++ we need to specifically say that a function is virtual in the parent class with the virtual keyword and also use the function destructor symbol ~.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

But how is this possible in python with no mention in python parent class to the function print_hello() being a virtual function.

I am assuming that the concept that python uses is that of virtual functions , if I am wrong please correct me and explain the concept.

>Solution :

Rather than thinking of this as being a matter of "virtual functions", it might be more useful to think of this as an example of "duck typing". In this expression:

self.print_hello()

we simply access the print_hello attribute of self (whatever it might be), and then call it. If it doesn’t have such an attribute, an AttributeError is raised at runtime. If the attribute isn’t callable, a TypeError is raised. That’s all there is to it. No assumptions are made about the type of self — we simply ask it to "quack like a duck" and see if it can.

The danger of duck typing is that it’s very easy to accidentally ask something to quack that does not in fact know how to quack — if you instantiate a parent_print and call print_word on it, it will fail:

abstract_print = parent_print()
abstract_print.print_word()
# raises AttributeError: 'parent_print' object has no attribute 'print_hello'

Python does have support for static type declarations and the concept of abstract classes, which can help you avoid mistakes. For example, if we run a static type checker (mypy) on your code as-is, we’ll get an error:

test.py:4: error: "parent_print" has no attribute "print_hello"

which is exactly correct — from a static typing perspective, it’s not valid to call print_hello since we haven’t established that all parent_print instances have such an attribute.

To fix this, we can declare print_hello as an abstract method (I’ll also clean up the names to match standard Python conventions, in the interest of building good habits):

from abc import ABC, abstractmethod

class ParentPrint(ABC):
    
    @abstractmethod
    def print_hello(self) -> None: ...

    def print_word(self) -> None:
        self.print_hello()
        
class ChildPrint(ParentPrint):
    
    def print_hello(self) -> None:
        print('Hello')
        
        
basic_print = ChildPrint()
basic_print.print_word()

Now the code typechecks with no issues.

The @abstractmethod decorator also indicates that the class is abstract ("pure virtual") and can’t be instantiated. If we attempt to create a ParentPrint, or any subclass of it that doesn’t provide an implementation of the abstract method, we get an error, both statically from mypy and at runtime in the form of a TypeError that is raised as soon as you try to instantiate the object (before you even try to call the abstract method):

abstract_print = ParentPrint()
# raises error: Cannot instantiate abstract class "ParentPrint" with abstract attribute "print_hello"
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading