Python Metaclasses Tutorial (with Examples)

Python Metaclass: In this tutorial, we will learn about the Python metaclass, define metaclass, and create singleton classes using metaclass. By Sapna Deraje Radhakrishna Last updated : June 26, 2023

Python Metaclass

A metaclass is the class of a class. A class defines how an instance of a class i.e.; an object behaves whilst a metaclass defines how a class behaves. A class is an instance of a metaclass.

A metaclass is most commonly used as a class factory. While an object is created by calling the class, Python creates a new class (when it executes the class statement) by calling the metaclass. Combined with the __init__ and __new__ methods, metaclasses allow implementing 'additional things' when creating a class, like replacing the class with something else entirely.

When the class statement is executed, Python first executes the body of the class statement as a normal block of code. The resulting namespace (a dict) holds the attributes of the class-to-be. The metaclass is determined by looking at the base classes of the class-to-be (metaclasses are inherited), at the __metaclass__ attribute of the class-to-be (if any), or the __metaclass__ global variable. The metaclass is then called with the name, bases, and attributes of the class to instantiate it.

Use-cases of metaclasses

The use-cases of metaclasses can be numerous, like

  1. Logging and profiling
  2. Dynamically adding new methods
  3. Dynamic resource locking/synchronization
  4. Registering the class at creation

Defining Python Metaclasses

Metaclasses are defined just like any other class, but they inherit from 'type'. The metaclass is automatically invoked when the class statement using metaclass ends. If a metaclass keyword is used on the other hand, the class assigned to it will be invoked instead of 'type',

Example

class MyMeta(type):
    def __new__(cls, clsname, superclasses, attrdict):
        print("class name:{}".format(clsname))
        print("super class name{}".format(superclasses))
        print("attribute dict{}".format(attrdict))
        return type.__new__(cls, clsname, superclasses, attrdict)

# Main Code
class test1:
    pass

class test2(test1, metaclass=MyMeta):
    pass

Output

(Observe that we see that MyMeta__new__ is invoked and not from 'type')

class name:test2
super class name(,)
attribute dict{'__module__': '__main__', '__qualname__': 'test2'}

Create Singletons using Metaclass

The singleton pattern is a design pattern that puts a constraint in the instantiation of a class to only one object. Singleton design pattern is used in cases where exactly one object is required.

Example

# Singleton Class
class MySingleton(type):
    _instances = {}
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(MySingleton, cls).__call__(*args, **kwargs)
        return cls._instances[cls]

# Main code
class SingletonClass(metaclass=MySingleton):
    pass

class RegularClass:
    pass

# Testing
test1 = SingletonClass()
test2 = SingletonClass()
print(test1 == test2)

test1 = RegularClass()
test2 = RegularClass()
print(test1 == test2)

Output

True
False

Comments and Discussions!

Load comments ↻





Copyright © 2024 www.includehelp.com. All rights reserved.