Open In App

How to Add Attributes in Python Metaclass?

Improve
Improve
Like Article
Like
Save
Share
Report

This article explains what a metaclass is in the Python programming language and how to add attributes to a Python metaclass. First, let’s understand what a metaclass is. This is a reasonably advanced Python topic and the following prerequisites are expected

To understand metaclasses, you need to understand Python classes. In most languages, a class is just a blueprint that describes how objects are created. In Python, classes are much more than that. Not only do classes define how instances are created, Python classes themselves are objects. Since classes are objects in Python, they are instances of a special class called metaclass and all metaclasses are instances of type class that create these class objects. Type class is the default metaclass responsible for creating classes. In simple words, Python objects are instances of a class and classes are instances of a metaclass. The following diagram summarizes this idea.

How to Add Attributes in Python Metaclass

 

When to use a Metaclass

  • If a class is defined and no metaclass is provided, the default type metaclass is used. If metaclass is specified then the base class is not an instance of type(), it will be used directly as the type for the base class.
  • If you want your class to change automatically on creation, use a metaclass.

Below is a simple demonstration of how attributes can be defined and added to a Metaclass in Python.

Creating a Metaclass

To add attributes to a metaclass in Python first we need to create a metaclass, in Python, we create a metaclass in the same way as a normal class which inherits a type class. Here, a metaclass named DemoMetaClass is created which inherits the type class as shown code below:

Python3




class DemoMetaClass(type):
    attr1 = 1
 
    def __new__(cls, name, base, defcl):
        obj = super().__new__(cls, name, base, defcl)
        obj.attr2 = 2
        return obj


  • __new__(): A method called before __init__(). Creates and returns an object. 
  • cls: It refers to the class on which __new__ is called in. 
  • name: Refer to the name of the class.
  • base: It is the parent class of the given class.
  • defcl: It specifies some definitions for the class.

Adding Attributes to Created Metaclass

Now that we have created a metaclass called DemoMetaClass and defined attr1 and atrr2 attributes while defining it, let’s create a base class that is an instance of that metaclass. As you can see we have created 2 classes first one is a default class Student and the second is Demo with metaclass as DemoMetaCLass.

Python3




# Default Class
class Student():
    pass
 
# Base class inherited DemoMetaClass metaclass
class Demo(metaclass=DemoMetaClass):
    pass
 
print("Student class is instance of ", type(Student))
print("Demo class is instance of ", type(Demo), end="\n\n")
print(f"DemoMetaClass \nattr1 => {Demo.attr1} \nattr2 => {Demo.attr2}\n")


Output:

The below image shows that by default the metaclass is a type class as in the case of the Student class while in the case of Demo the metaclass is DemoMetaClass, As Demo is the base class of DemoMetaClass it also possesses attributes of its metaclass, which is printed in the output.

 

Adding a new attribute

We can also add attributes to the metaclass as we do with the usual class in Python, As you can see in the output above a new attribute named attr3  with value 3 is been added to DemoMetaClass.

Python3




# Adding a new attribute attr3 to DemoMetaClass
DemoMetaClass.attr3 = 3
print(f"DemoMetaClass \nattr1= > {Demo.attr1} \nattr2 = > {Demo.attr2}\nattr3= > {Demo.attr3}")


Output:

How to Add Attributes in Python Metaclass

 

Complete Code

Python3




# Custom MetaClass Defined for demo
class DemoMetaClass(type):
    attr1 = 1
 
    def __new__(cls, name, base, defcl):
        obj = super().__new__(cls, name, base, defcl)
        obj.attr2 = 2
        return obj
 
# Default Class
 
 
class Student():
    pass
 
# Base class inherited DemoMetaClass metaclass
 
 
class Demo(metaclass=DemoMetaClass):
    pass
 
 
print("Student class is instance of ", type(Student))
print("Demo class is instance of ", type(Demo), end="\n\n")
print(f"DemoMetaClass \nattr1 => {Demo.attr1} \nattr2 => {Demo.attr2}\n")
 
# Adding a new attribute attr3 to DemoMetaClass
DemoMetaClass.attr3 = 3
print(
    f"DemoMetaClass \nattr1 => {Demo.attr1} \nattr2 => {Demo.attr2}\nattr3 => {Demo.attr3}")


Output:

Student class is instance of  <class 'type'>
Demo class is instance of  <class '__main__.DemoMetaClass'>

DemoMetaClass 
attr1 => 1 
attr2 => 2

DemoMetaClass 
attr1 => 1 
attr2 => 2
attr3 => 3


Last Updated : 18 Apr, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads