Metadata Class

Everything is object in python, so class is aslo object named Metadata Calss.

How to use define and use metaclass

The basic metadata class is type, you can define an object from this type.

PythonClass = type('class name', (supper class,), attributes)

The above will retruen a calss. If you want to define a new class, you can inhiert from type as follow:

class Single(type):
    pass

Now Single is a new metadata class, then you can use it to define a new class.

class Logger(metaclass=Single):
    pass

Then Logger will try to use Single to help create the class.

What should we implement a metacalss

In order to create an object or class, there are three special methods __new__, __init__, and __call__. When we initial an object, it will call new first to malloc the memory and then use init to set some properities. But what’s method __call__, it just a special method, when you call ClassName(*args, **kwargs), then it will call method __call__ automactically. So we can change the inital process when we create a class object.

Here is an example, how to use meta calss define Single class.

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

Define object

class Logger(metaclass=Single):
    pass

When you call Logger() to create an object, this it will call Single’s __new__, and __init__, then it will return an class object, then it will call __call__ method of metaclass. There is an very important notice: If you special __call__ method, then the methods __init__ and __new__ of object will never been call, if you want it still be called. For this case, it will call __init__ and __new__, because super class will call them automatically.

Example Code

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

#*************************************************************************
	# File Name: test.py
	# Author: Guan Wei
	# Mail: wguan@microstrategy.com 
	# Created Time: Sun Oct 30 22:49:17 2022
#************************************************************************

class ClassA(type):
    def __new__(cls, name, base, dct):
        print("metadata class")
        return type.__new__(cls, name, base, dct)

    def __call__(cls, *args, **kwargs):
        print("hello world!")
        print('call ClassA instance')
        instance = cls.__new__()
        # instance.__new__()
        # instance.__init__()
        return instance



class ClassB(object):
    __metaclass__ = ClassA

    def __init__(self):
        print("Call classb init")

    def __new__(cls):
        print("calss classb new")
        return object.__new__(cls)

if __name__=='__main__':
    x=ClassB()
Built with Hugo
Theme Stack designed by Jimmy