A class is more or less a fancy wrapper for a dict of attributes to objects. When you instantiate a class you can assign to its attributes, and those will be stored in foo.__dict__; likewise, you can look in foo.__dict__ for any attributes you have already written.

This means you can do some neat dynamic things like:

class Employee: pass
def foo(self): pass
Employee.foo = foo

as well as assigning to a particular instance. (EDIT: added self parameter)

Answer from Katriel on Stack Overflow
๐ŸŒ
Python documentation
docs.python.org โ€บ 3 โ€บ tutorial โ€บ classes.html
9. Classes โ€” Python 3.14.4 documentation
There is a simple way to call the base class method directly: just call BaseClassName.methodname(self, arguments). This is occasionally useful to clients as well. (Note that this only works if the base class is accessible as BaseClassName in the global scope.) Python has two built-in functions that work with inheritance:
๐ŸŒ
Quora
quora.com โ€บ Why-would-you-want-to-have-an-empty-class-in-Python
Why would you want to have an empty class in Python? - Quora
Answer (1 of 2): The most common case is for defining your own custom exceptions. Those are normally empty classes inheriting from the most appropriate existing exception in the hierarchy.
Top answer
1 of 2
3

When you create a new class, you are creating a new type. This newly created type may have some properties, or may not. These properties allow to hold data, methods etc.

Empty class that doesn't inherit any base class would be useful as placeholder.

class ServiceWrapper(object):
    pass

def sendMessage(svc:ServiceWrapper):
    #do something
    #pass

On the other hand, empty classes that inherit other classes is a very common pattern. Specially when defining user exceptions.

class Networkerror(RuntimeError):
    pass

try:
    raise Networkerror()
except Networkerror:
    #do something
    #pass

Also recently, the python collections.abc allows creating interface like functionalities.

class ServiceWrapper(ABC):
    @abstractmethod
    def send(self):...

def sendMessage(svc:ServiceWrapper):
    svc.send()
    #pass
2 of 2
0

I recently found myself using empty Python classes as unique "tags" for an observer system.

For example, something like this...

from collections import defaultdict

class OnCreate:
    pass

class OnModify:
    pass

class OnDelete:
    pass

class ObserverSystem:
    def __init__(self):
        self.observers = defaultdict(list)

    def register(self, event, callback):
        self.observers[event].append(callback)

    def notify(self, event, *args, **kwargs):
        for callback in self.observers[event]:
            callback(*args, **kwargs)

observer = ObserverSystem()
observer.register(OnCreate, lambda entity: print(f"Entity {entity} created"))
observer.register(OnModify, lambda entity: print(f"Entity {entity} modified"))
observer.register(OnDelete, lambda entity: print(f"Entity {entity} deleted"))

observer.notify(OnCreate, 1)
observer.notify(OnModify, 2)
observer.notify(OnDelete, 3)

I guess, I could have used a of numeric value, or even a string as the "tag", but the class is unique, it's hashable so I can use it as dict key, etc. Seems to work well.

๐ŸŒ
Towards Data Science
towardsdatascience.com โ€บ home โ€บ latest โ€บ master class inheritance in python
Master Class Inheritance in Python | Towards Data Science
March 5, 2025 - Letโ€™s build the medium_subscriber class, which will acquire the attributes and the methods of the medium_user class, previously defined. To gradually understand how class inheritance works, we can create an empty class, that simply inherits the functionalities from the other class.
๐ŸŒ
Readthedocs
jfine-python-classes.readthedocs.io โ€บ en โ€บ latest โ€บ construct.html
Constructing classes โ€” Objects and classes in Python tutorial
The method resolution order (mro) attribute __mro__ is computed from the bases of the class. It provides support for multiple inheritance. ... For now the important thing is that even the empty class has attributes.
๐ŸŒ
Built In
builtin.com โ€บ software-engineering-perspectives โ€บ python-inheritance
Python Class Inheritance Explained | Built In
Letโ€™s import the random forest classifier from Scikit-learn and define an empty class called CustomClassifier. The CustomClassifier will take the RandomForestClassifier class as an argument: from sklearn.ensemble import RandomForestClassifier class CustomClassifier(RandomForestClassifier): pass ยท We will specify a test_size in our init method that allows us to specify the size of our testing and training samples. We will also use the super method to allow our custom class to inherit the methods and attributes of the random forest class.
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ how-to-create-an-empty-class-in-python
How to create an empty class in Python? - GeeksforGeeks
December 29, 2020 - # Python program to demonstrate # empty class class Employee: pass # Driver's code # Object 1 details obj1 = Employee() obj1.name = 'Nikhil' obj1.office = 'GeeksforGeeks' # Object 2 details obj2 = Employee() obj2.name = 'Abhinav' obj2.office = 'GeeksforGeeks' obj2.phone = 1234567889 # Printing details print("obj1 Details:") print("Name:", obj1.name) print("Office:", obj1.office) print() print("obj2 Details:") print("Name:", obj2.name) print("Office:", obj2.office) print("Phone:", obj2.phone) # Uncommenting this print("Phone:", obj1.phone) # will raise an AttributeError Output:
Find elsewhere
๐ŸŒ
BioChemiThon
biochemithon.in โ€บ home โ€บ python | how to create an empty class?
Python | How to Create an Empty Class? - BioChemiThon
August 15, 2023 - It is common to create empty classes when you are defining a class that you plan to fill in later with properties and methods. This allows you to create the class skeleton with the appropriate class name and inheritance (if needed) without needing to define any properties or methods immediately.
๐ŸŒ
TutorialsPoint
tutorialspoint.com โ€บ how-to-create-an-empty-class-in-python
How to create an empty class in Python?
September 15, 2022 - class Student: pass # Creating objects st1 = Student() st1.name = 'Henry' st1.age = 17 st1.marks = 90 st2 = Student() st2.name = 'Clark' st2.age = 16 st2.marks = 77 st2.phone = '120-6756-79' print('Student 1 = ', st1.name, st1.age, st1.marks) print('Student 2 = ', st2.name, st2.age, st2.marks, st2.phone) Student 1 = Henry 17 90 Student 2 = Clark 16 77 120-6756-79 ยท Using the pass statement, we can also create empty functions and loops.
๐ŸŒ
CodingNomads
codingnomads.com โ€บ creating-python-objects-from-classes
Python Classes, Objects and Instance Variables
In this code snippet, you've defined an empty class. Then, you created an instance of that empty class.
๐ŸŒ
W3Schools
w3schools.com โ€บ python โ€บ python_inheritance.asp
Python Inheritance
Now we have successfully added the __init__() function, and kept the inheritance of the parent class, and we are ready to add functionality in the __init__() function. Python also has a super() function that will make the child class inherit all the methods and properties from its parent:
Top answer
1 of 3
2

Note: This post contains two different implementation techniques to allow for what you want.


Solution Through Indirection

The easiest way around this issue is to refactor the code so that the child classes does not directly override the function used by the public interface.

Instead provide the public functionality directly in the base-class, and make children override a "worker" (implementation detail) of said function that is later called by the function invoked "from the outside".


Example Implementation

class Base (object):
    def get_message (self):
        try:
            return self.get_message_impl ()
        except Exception as detail:
            print ("error:", detail)    
        return None

    def get_message_impl (self):
        raise Exception ("Not Implemented")
class Foo (Base):
    def get_message_impl (self):
        return "Hello World";
class Bar (Base):
    def get_message_impl (self):
        raise Exception ("Bar.get_message_impl always fails!")
f = Foo ()
b = Bar ()

f_msg = f.get_message ()
b_msg = b.get_message ()

print ("f_msg:", f_msg)
print ("b_msg:", b_msg)

output

error: Bar.get_message_impl always fails!
f_msg: Hello World
b_msg: None


opt-in protection

If you would like to maintain the possibility to override the public functionality presented in the base class, while still being able to easily call a "protected" version of the functions at a later time, you could create a simply wrapper such as the below:

class Base (object):
    class Protected (object):
        def __init__ (self, target):
            self.target = target

        def get_message (self):
            try:
                return self.target.get_message ()
            except Exception as detail:
                print ("error:", detail)
            return None

    def __init__ (self):
        self.protected = self.Protected (self)

    def get_message (self):
        raise Exception ("Not Implemented")
class Foo (Base):
    def get_message (self):
        return "Hello World";
class Bar (Base):
    def get_message (self):
        raise Exception ("Bar.get_message_impl always fail!")
f = Foo ()
b = Bar ()

f_msg = f.protected.get_message () # protected from failure
b_msg = b.protected.get_message () # protected from failure

b_msg = b.get_message ()           # will raise exception
2 of 3
2

NotImplementedError is an exception; don't return it, raise it as an exception:

class Crawler():
    def get_image_source_url(self, image_page_soup):
        raise NotImplementedError("method get_image_source_url must be implemented")

    def get_image_thumbnail_url(self, image_page_soup):
        raise NotImplementedError("method get_image_thumbnail_url must be implemented")

    def get_tags_container(self, image_page_soup):
        raise NotImplementedError("method get_tags_container must be implemented")

You don't need to 'wrap' anything here. If the subclass implements the method, the original method won't be called an no exception is raised.

If further processing is needed, and the subclass implementation is optional but should not be visible to the outside API, you could require subclasses to implement a method by a different name, called from the base class method:

class Crawler():
    def _image_source_url_implementation(self, image_page_soup):
        raise NotImplementedError("method get_image_source_url must be implemented")

    def get_image_source_url(self, image_page_soup):
        try:
            url = self._image_source_url_implementation(image_page_soup)
        except NotImplementedError:
            # do something default
            url = 'something else'
        # process the produced URL further
        return processed_result

Here self.get_image_source_url() delegates to an optional self._image_source_url_implementation() method.

๐ŸŒ
Medium
medium.com โ€บ @amit25173 โ€บ python-inheritance-explained-with-examples-877833d66403
Python Inheritance Explained (With Examples) | by Amit Yadav | Medium
January 22, 2025 - Yes, you read that right โ€” thereโ€™s ... everything defined in the Animal class. This might surprise you, but inheritance works even when the child class is empty....
๐ŸŒ
Intellipaat
intellipaat.com โ€บ community โ€บ 70671 โ€บ empty-class-object-in-python
Empty class object in Python - Intellipaat Community
Python ยท Empty class object in Python ยท Empty class object in Python ยท Welcome to Intellipaat Community. Get your technical queries answered by top developers! 30.9k questions ยท 32.9k answers ยท 500 comments ยท 665 users ยท All categories ยท
Published ย  February 16, 2021