Follow us

Python OOPs Tips

I was exploring bit around Python oops concepts and below few interesting concepts I would like to share, which generally everyone use with any programming.

  • .       With Python, there is no inbuilt interface class concept, then I was curious to know, how we can handle basic OOPS concept like defining class signature which then should be implemented by child/concreate class. So yes, there options available, which you can use to manage this either using abstractclass and methods or use available interface package.
  • .       Similarly, second my curiosity was, how I can manage Dependency injection, so that I can keep my code base loosely coupled and I able to find those concept as well to manage DI.
  • .       Every project has some reusable code base and you surely would not like to repeat same with every python file/classes or projects. So there is concept to expose those reusable code as module and then you can import and use it with rest of files/projects.
  • .       Other thing, If I want to build some rule on my python class, which I then want to make sure it apply while using it by other child classes, so to do that, I could create Metaclass for the same and write all my rules, I wanted to have for my python class.

Example: Interface/abstract class – usage with Python

Here I have used abstractclass and methods for this example:

The abc package contains some handy tools for defining Abstract Base Classes. ABCs can have one or more abstract method or property. The methods/properties must be overridden by any inheriting class, otherwise it the class can not be instantiated.

Let’s see an example:

 

from abc import ABC, abstractmethod

 

class Communication(ABC):

    @abstractmethod

    def Send(self):

        pass

   

    @abstractmethod

    def Fetch(self):

        pass

 

class Email(Communication):

    def Send(self):

        print("Send email test successful")

    def Fetch(self):

        print("Fetch email test successful")

 

email = Email()

email.Send()

email.Fetch()

 

Here with above example, if you do not implement any of the method of Communication class inside your child class i.e. Email, let say you remove "Fetch" method from Email class and then try run this, it will give you error as : "TypeError: Can't instantiate abstract class Email with abstract method Fetch"

If you don’t want your method to have a default implementation, you can leave the function body empty (just write a single pass statement) or raise a NotImplementedError

Handle DI (Dependency Injection):

With below example, I have DbConnectionInterface with connect method and then there is SQLServerConnection class which implement that interface and similarly other class i.e. MongoDBConnection which also implement same interface with connect method. Now I have LoadData class which actually load data from various data source like SQL server, MongoDB or any new database in future, so part of LoadData classs I have pass db_connection as DbConnectionInterface class, so that consumer of this LoadData class will decide which database need to be used. So while calling LoadData class below there I have passed SQLServerConnection class object with first call and then with second call I passed MongoDBConnection class object. So my LoadData class is not dependent on any of my database and it is injecting via __init__ during object creation by consumer.

 

from abc import ABC, abstractmethod

 

class DbConnectionInterface(ABC):

    @abstractmethod

    def connect(self):

        pass

 

class SQLServerConnection(DbConnectionInterface):

    def connect(self):

        print("Connect to sql db")

 

class MongoDBConnection(DbConnectionInterface):

    def connect(self):

        print("Connected to mongo db")

 

class LoadData():

    def __init__(self, db_connection: DbConnectionInterface):

        self._db_connection = db_connection

        db_connection.connect()

 

 

LoadData(SQLServerConnection()) #output: Connect to sql db

LoadData(MongoDBConnection()) #output: Connected to mongo db

 

Manage reusable code: 

To create a module just save the code you want in a file with the file extension  should be .py.

Created module - Save this code in a file named mymodule.py

 

def greeting(name):

  print("Hello, " + name)

 

user = {

  "name": "John",

  "age": 20

}

 

Now to consume above created module, created other python file.

Import the module named mymodule, and access the person object or greeting method:

 

import mymodule

 

mymodule.greeting("Jonathan") #output: Hello Jonathan

print(mymodule.person1["age"])  #output: 20

 

NOTE: Now if you have multiple projects like if you are working on microservice architecture, then you should expose reusable module into pypi package and then import directly from python package to use.

Metaclass for managing/creating rules for class to follow while implementing/using:

In this example you have base class which then will be inherit by multiple classes, but you want to apply behaviour that, your base class cannot be inherit with multiple child class i.e. ClassA inherited base class, that is fine and similarly ClassB also inherited base class that is also fine but now, there is classC which is inheriting ClassA and ClassB both together, so as both class has inherit reference of base class, so it should throw error message to not allowing this. You can do all these kind of behaviour change/update using metaclass:

# my metaclass

class MultiBases(type):

    # overriding __new__ method with my rules

    def __new__(cls, clsname, bases, clsdict):

        if len(bases)>1:

            raise TypeError("Inherited multiple base classes")

        # call __init__ of type class

        return super().__new__(cls, clsname, bases, clsdict)

 

# my base class

class Base(metaclass=MultiBases):

    pass

 

# no error is raised

class A(Base):

    pass

 

# no error is raised

class B(Base):

    pass

 

# This will raise an error (TypeError: Inherited multiple base classes)

class C(A, B):

    pass

Categories/Tags: python

Recent Articles

1

AWS Saving Plan - Cost optimization tips

2
3

AWS RDS Key Concepts & Why you should use it?

4
5

Open-Search/Kibana - Multi Tenancy Setup

See All Articles