# python中MetaClass的一些用法

[En]

Metaclass has such a concept in many programming languages, we all know that the class can create objects, the class itself is also an object, since it is an object, then it must also be created, metaclass is specifically used to create class objects, so, this provides us with the ability to manipulate or listen to classes.

[En]

Usually we create a class in this way:

class MyClass(object):
def method(self):
return 1

instance1 = MyClass()
print(instance1.method())


[En]

If you think of a class as an object and use a metaclass, we create a class like this:

def method(self):
return 1

klass = type('MyClass', (object,), {'method': method})
instance1 = klass()
print(instance1.method())


[En]

If you look at the way you write it, it doesn’t make much difference. What’s really useful about MetaClass is that we can customize metaclasses. Let’s take a look at a piece of code:

class RevealingMeta(type):
def __new__(mcs, name, bases, namespace, **kwargs):
print(mcs, "__new__ called")
return super().__new__(mcs, name, bases, namespace)

@classmethod
def __prepare__(metacls, name, bases, **kwargs):
print(metacls, "__prepare__ called")
return super().__prepare__(name, bases, **kwargs)

def __init__(cls, name, bases, namespace, **kwargs):
print(cls, "__init__ called")
super().__init__(name, bases, namespace)

def __call__(cls, *args, **kwargs):
print(cls, "__call__ called")
return super().__call__(*args, **kwargs)



[En]

The above code can be regarded as a fixed way of writing, and the more important concept is the timing of calling these four methods:

• __new__ 当某个类被创建的时候会调用
• __prepare__ 在创建类的时候，可以传入额外的字典 class Klass(metaclass=Metaclass, extra="value"):,这个方法就是用来创建接收dict的，所以这个方法会在 __new__前边调用
• __init__ 这个方法算是对 __new__的一些补充
• __call__ 这个方法会在类被创建的时候调用

[En]

Let’s use the metaclass created by the above code to create a class:

class RevealingMeta(type):
def __new__(mcs, name, bases, namespace, **kwargs):
print(mcs, "__new__ called")
return super().__new__(mcs, name, bases, namespace)

@classmethod
def __prepare__(metacls, name, bases, **kwargs):
print(metacls, "__prepare__ called")
return super().__prepare__(name, bases, **kwargs)

def __init__(cls, name, bases, namespace, **kwargs):
print(cls, "__init__ called")
super().__init__(name, bases, namespace)

def __call__(cls, *args, **kwargs):
print(cls, "__call__ called")
return super().__call__(*args, **kwargs)

class RevealingClass(metaclass=RevealingMeta):
def __new__(cls, *args, **kwargs):
print(cls, "__new__ called")
return super().__new__(cls)

def __init__(self):
print(self, "__init__ called")
super().__init__()


[En]

If the code is executed directly at this time, it will print out:

 __prepare__ called
__new__ called
__init__ called
__call__ called


[En]

This means that the above methods will be called as soon as the class is created, and the invocation of these methods has nothing to do with the creation of the instance.

instance12 = RevealingClass()


[En]

After the above print, it will print out:

 __new__ called
__init__ called


[En]

This is the basic use of metaclass. * it is generally used in a lot of framework, but it is also error-prone. We can specify a metaclass for a class at will, and if the metaclass does not implement these methods, it may crash. *

Original: https://www.cnblogs.com/machao/p/8708584.html
Author: 马在路上
Title: python中MetaClass的一些用法

(0)