Python3 metaclass memo

Python3 metaclass memo

A note on what Python beginners have learned about Python 3 metaclasses The comments in the code are intended for console output. We would appreciate it if you could point out any mistakes or improper expressions.

What is a metaclass?

If you want to find out which class type an instance is, you can use type ().

class Hoge:
    pass
h = Hoge()
print(type(h))
# <class '__main__.Hoge'>

Try applying type () to the Hoge class as well.

print(type(Hoge))
# <class 'type'>

This indicates that the Hoge class itself is an instance of type type. Just as h is an instance of the Hoge class, the Hoge class is also an instance of the type class. *** A class defined in Python3 becomes an instance of a special class (metaclass) called type. *** Normally, when a class is defined, type (classname, superclasses, attributes_dict) with three arguments is called, and an instance of the class is created. It is also possible to explicitly give three arguments to the type class and create a class instance instead of the "normal" definition method. The above Hoge class can be defined as ↓ using type. (Pass the class name in the first argument, the tuple of the parent class in the second argument, and the namespace dictionary in the third argument)

Hoge = type('Hoge', (), {})
h = Hoge()
print(type(h))
# <class '__main__.Hoge'>

The type class that creates a class instance is like a factory that creates (an instance of) a class and is called a *** metaclass ***. When the interpreter faces the declaration of the Hoge class, by default \ _ \ _ new \ _ \ _ of the type class is called and a class instance is created, but you can customize the metaclass by inheriting this type class. .. The following is an example of setting the MetaTest class that inherits type instead of the default type as the metaclass when declaring the class.

class MetaTest(type):
    def __new__(cls, clsname, superclasses, attributedict):
        print("Metaclass testing")
class HogeHoge(metaclass=MetaTest):
    pass
#Metaclass testing
h = HogeHoge()
# TypeError: 'NoneType' object is not callable

MetaTest inherits from the default metaclass, the type class, and overrides the \ _ \ _ new \ _ \ _ method that creates a class instance. Here, the character string is just output without creating a class instance. Therefore, when declaring a HogeHoge class with MetaTest set as a metaclass, MetaTest. \ _ \ _ New \ _ \ _ that just returns a string instead of type. \ _ \ _ New \ _ \ _ that creates a class instance Called. The console also displayed "Test Metaclass". The next time I tried to instantiate the HogeHoge class, I got an error. The MetaTest class has not created an instance of the HogeHoge class (is a None object created?). If you override the parent class type \ _ \ _ new \ _ \ _, the class instance will not be created. Calling type. \ _ \ _ New \ _ \ _ in the return value of \ _ \ _ new \ _ \ _ to return a class instance or overriding \ _ \ _ init \ _ \ _ will work (\ _ \ _ new ) Class instance created when _ \ _ was called first?).

class MetaTestA(type):
    def __new__(cls, clsname, superclasses, attributedict):
        print("Metaclass A test")
        return type.__new__(cls, clsname, superclasses, attributedict)
class MetaTestB(type):
    def __init__(cls, clsname, superclasses, attributedict):
        print("Metaclass B test")
class HogeHogeA(metaclass=MetaTestA):
    pass
#Metaclass A test
class HogeHogeB(metaclass=MetaTestB):
    pass
#Metaclass B test
a = HogeHogeA()
b = HogeHogeB()
print(type(a))
# <class '__main__.HogeHogeA'>
print(type(b))
#  <class '__main__.HogeHogeB'>

Example of using metaclass (Singleton)

You can control the behavior of class instances by customizing the metaclass. The here site that I referred to this time introduces a Singleton pattern like ↓ that utilizes metaclasses.

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

class SingletonClass(metaclass=Singleton):
    pass
class RegularClass():
    pass
x = SingletonClass()
y = SingletonClass()
print(x == y)
# True
x = RegularClass()
y = RegularClass()
print(x == y)
# False

An instance with a \ _ \ _ call \ _ \ _ method (it seems to be called able) can call \ _ \ _ call \ _ \ _ like a function with the instance name (). Singleton, a metaclass that inherits type, overrides the type class \ _ \ _ call \ _ \ _. \ _ \ _ Call \ _ \ _ is called every time a SingletonClass class (a class that is an instance of Singleton) with Singleton set as a metaclass is described in the format of SingletonClass () (every time SingletonClass is instantiated). Will be done. Inside \ _ \ _ call \ _ \ _, it checks if the instance is stored in \ _instances, and if the instance does not exist, the \ _ \ _ call \ _ \ _ method of type, which is the parent class of Singleton, is called. , SingletonClass is instantiated (here \ _ \ _ call \ _ \ _ seems to instantiate SingletonClass, but I'm not sure about the details). If an instance already exists in \ _instances, no new instance will be created. On the other hand, RegularClass, whose metaclass is the default type class, is instantiated each time.

reference

https://www.yunabe.jp/docs/python_metaclass.html https://www.python-course.eu/python3_metaclasses.php https://realpython.com/python-metaclasses/ https://teratail.com/questions/180387

Recommended Posts

Python3 metaclass memo
Python memo
python memo
python memo
Python memo
Python memo
Python memo
[Python] Memo dictionary
python beginner memo (9.2-10)
★ Memo ★ Python Iroha
[Python] EDA memo
Python 3 operator memo
[My memo] python
[Python] Basemap memo
Python beginner memo (2)
[Python] Numpy memo
My python environment memo
Python module (Python learning memo ④)
Visualization memo by Python
Python test package memo
[Python] Memo about functions
python regular expression memo
Binary search (python2.7) memo
[My memo] python -v / python -V
Python3 List / dictionary memo
[Memo] Python3 list sort
Python Tips (my memo)
[Python] Memo about errors
DynamoDB Script Memo (Python)
Python basic memo --Part 2
python recipe book Memo
Basic Python command memo
Python OpenCV tutorial memo
Python basic grammar memo
TensorFlow API memo (Python)
python useful memo links
Python decorator operation memo
Python basic memo --Part 1
Effective Python Memo Item 3
Divisor enumeration Python memo
Python memo (for myself): Array
Python exception handling (Python learning memo ⑥)
Python execution time measurement memo
Python
Twitter graphing memo with Python
[Line / Python] Beacon implementation memo
Python and ruby slice memo
Python code memo for yourself
Raspberry Pi + Python + OpenGL memo
Python basic grammar (miscellaneous) Memo (3)
Python immutable type int memo
Python memo using perl --join
python metaclass and sqlalchemy declareative
Python basic grammar (miscellaneous) Memo (2)
[MEMO] [Development environment construction] Python
[Python] virtualenv creation procedure memo
Python basic grammar (miscellaneous) Memo (4)
Regarding speeding up python (memo)
Python environment construction memo on Windows 10
Difference between java and python (memo)
[Python] Operation memo of pandas DataFrame