arnabpal.me
HomeAboutProjectsCoursesBlogContact
HomeBlog

Implementing Interfaces in Python

Arnab PalArnab Pal
March 2, 2023Updated May 2026
Implementing Interfaces in Python

On this page

  • Using ABCMeta
  • Defining own Metaclass
On this page

On this page

  • Using ABCMeta
  • Defining own Metaclass
Share:

Python doesn’t provide explicit support for interfaces like Java or Go. But we can implement interfaces and can enforce them at the time of class definition. The interface is generally a good programming practice where we can enforce different entities that have the same method. There are two kinds of approaches to doing this. The first one is quite simple. Python offers some metaclasses to do the job. And the second one is where we can define a metaclass and include the logic in the metaclass explicitly.

Using ABCMeta

from abc import ABCMeta, abstractmethod

class BaseClass(metaclass=ABCMeta):

def __init__(self):
pass

@abstractmethod
def method_1(self):
raise NotImplementedError()

@abstractmethod
def method_2(self):
raise NotImplementedError()

So here we defined a class which contains 2 methods and we want some other classes which inherit from the above class must define these two methods. And the base class is a metaclass so you can’t instantiate it. If you try to do the same will get this error.

Traceback for instantiating BaseClass with abstractmethod present
Traceback for instantiating BaseClass with abstractmethod present

Now define a class which only enforces the method_1

class A(BaseClass):

def __init__(self, a, b):
self.a = a
self.b = b
def method_1(self):
print("calling method 1")

Now if we want to instantiate class A, we will get this error

Traceback for instantiate a class with only one method defined
Traceback for instantiate a class with only one method defined

So now if we want to create a class which inherits from BaseClass then we have to define the abstract methods method_1 and method_2 . After that, we can instantiate the class.

class A(BaseClass):

def __init__(self, a, b):
self._a = a
self._b = b
def method_1(self):
print("calling method 1")
def method_2(self):
print("calling method 2")
Instantiation is successfull after we define both methods

Defining own Metaclass

Defining your own metaclass and controlling instance creation or class creation is not recommended unless you need more control over class creation, enforcing certain coding practices.

Here we first created a metaclass named BaseMeta . For explicit metaclass declaration, your class must inherit from type Class. Here the __new__ method contains the logic for enforcing interfaces. For that, we defined a structure where all the methods signature will be defined in BaseClass . Any child class which wants to implement all the methods defined BaseClass must inherit from BaseClass . One more point here we restricted the instance creation of any class whose metaclass is BaseMeta.

def _is_dunder(name):
return name.startswith('__') and name.endswith('__') and len(name)>4

class BaseMeta(type):

def __new__(cls, clsname, bases, clsdict):
method_not_defined = []
if clsname != 'BaseClass':
if BaseClass in bases:
base_cls_dict = BaseClass.__dict__
for name, meth in base_cls_dict.items():
# checks which methods are defined for enforcing in sub classes
# and also checks callables are not dunder
if (not _is_dunder(name)) and callable(meth):
# checks if methods are defined in the current class
# if not then raise Type Error
if name not in clsdict:
method_not_defined.append(name)
if method_not_defined:
raise TypeError(f'{", ".join(method_not_defined)} are not defined')
return super().__new__(cls, clsname, bases, clsdict)

def __call__(self, *args, **kwargs):
raise TypeError("Can't instantiate directly")

class BaseClass(metaclass=BaseMeta):

def __init__(self):
pass

def method_1(self):
pass
def method_2(self):
pass

Now if we want to instantiate the BaseClass then will get this error

Tracback for directly instantiate BaseClass

Now let’s see if we define a class A with no methods enforced

class A(BaseClass):
pass

If we try to run the code then we will get this error

Now look what happens if we define only one method

class A(BaseClass):

def method_1(self):
print("in method 1")

So the code will not throw any error at the runtime if we define all the methods defined in BaseClass

class A(BaseClass):

def method_1(self):
print("in method 1")

def method_2(self):
print("in method 2")

It is recommended to use ABCMeta rather than defining your own metaclass .

Arnab Pal
Written by

Arnab Pal

Backend Engineering · AI Systems · Distributed Architecture

Building scalable backend systems, AI products, and distributed architectures. I write about production engineering, LLMs in the real world, and the messy bits between system design and shipping.

GitHubLinkedInXWebsite
Arnab Pal
Arnab Pal
Backend Engineering · AI Systems · Distributed Architecture
GitHubLinkedInXWebsite

Newsletter

Backend, AI, and distributed-systems essays — straight to your inbox. No fluff.

No spam ever. Unsubscribe anytime.

Go deeper

Master production backend systems

Cohort-based courses on Django at scale, distributed systems, and shipping LLMs — same opinions you read here.

Explore courses
Arnab Pal
Arnab Pal
Backend Engineering · AI Systems · Distributed Architecture
GitHubLinkedInXWebsite

Newsletter

Backend, AI, and distributed-systems essays — straight to your inbox. No fluff.

No spam ever. Unsubscribe anytime.

Go deeper

Master production backend systems

Cohort-based courses on Django at scale, distributed systems, and shipping LLMs — same opinions you read here.

Explore courses

arnabpal.me

A platform for software engineering insights, courses, and projects focused on backend development and AI applications.

Quick Links

  • Home
  • About
  • Projects
  • Courses
  • Blog

Resources

  • GitHub Projects
  • Newsletter
  • Privacy Policy
  • Terms of Service

© 2026 Arnab Pal. All rights reserved.