Python metaclass (type () and the metaclass that)

1. What is the metaclass

As we all know, the object is instantiated from a class, class is a template object, and the python are all objects, classes are objects that are created by Yuan class (type), so metaclass is the class of the class is a template class

2. Another way to create a class

Under normal circumstances, we declare a class using the class keyword, like

class Demo:
    def __init__(self,name,age):
        self.name = name
        self.age = age
    
    def output(self):
        print("name is " + str(self.name) + " age is " + str(self.age))

if __name__ == '__main__':
    demo = Demo("Bob",18)
    demo.output()

python in all classes are created by type, so when we type will explicitly use type () function looks like<class type>

>>> class Demo:
	pass

>>> type(Demo)
<class 'type'>
>>> demo = Demo()
>>> type(demo)
<class '__main__.Demo'>

By instantiating the class type of the object is out <class 类名>, so that all validation and more classes are instantiated from the derived type metaclass

By creating a class type

Can look at the type of document, type can be passed three parameters, object_or_name, bases, dict, when only one parameter is the object, the return type of the object, as is the case most frequently used when an incoming name, bases when dict parameter returns a class, name is the name of the class, the base class is a tuple bases, dict a dictionary class attributes and methods

class type(object):
    """
    type(object_or_name, bases, dict)
    type(object) -> the object's type
    type(name, bases, dict) -> a new type
    """

We use the type rewrite the above class Demo

# 模拟__init__()
def __init__(self,name,age):
    self.name = name
    self.age = age

def output(self):
    print("name is " + str(self.name) + " age is " + str(self.age))


class_name = 'Demo'
class_bases = (object,)
class_dict = {
    '__init__':__init__,
    'output': output,
}

# type(name, bases, dict) -> a new type
Demo = type(class_name,class_bases,class_dict)
demo = Demo('Bob',18)
demo.output()  # name is Bob age is 18

Indeed, when using the class definition of each class, are performed type () method

3. MetaClass

Since all classes are created by the type of behavior that we can create the kind of control, which requires the use metaclass metaclass

  • Yuan class is used to create a class, in essence, is a class that inherits from type
  • __new__It is the real constructor, to allocate memory space__new__(cls: type, name: str, bases: Tuple[type, ...], namespace: Dict[str, Any]) -> type
def add(self, value):
    print('add one value')
    self.append(value)


class ListMetaclass(type):
    def __new__(mcs, name, bases, namespace):
        namespace['add'] = add
        return type.__new__(mcs, name, bases, namespace)


class MyList(list, metaclass=ListMetaclass):
    pass


li = MyList()
li.add(1)
print(li)

When a class definition of class, the brackets can be specified metaclass, created after a specified __metaclass__, python creating class, you will first check if any __metaclass__, and if so, this will create an object method, no parent will find step by step up there is no class that, if found in the current package has not been found, it will use the default type is created (call metaclass.__new__())

It is noteworthy that, if we do define the class, passing in a keyword in the class declaration metaclass = ListMetaclass at, so if there is an incoming __call__ this metaclass function, this function will overwrite __call__ MyList class the __new__ function. Why is this? Please recall that when we instantiate MyList, the use of the statement is L1 = MyList (), and we know __ role call__ function is to make the object after the class is instantiated can be like a function call. That is the object MyList after ListMetaclass instantiated, but MyList () call is ListMetaclass of __call__ function. In addition, it is worth mentioning that, if declared at the class, we let MyList inherited ListMetaclass, then ListMetaclass of __call__ function will not overwrite the __new__ MyList function.

Metaclass rarely used under normal circumstances, but there will still be like ORM in applications, ORM (object-relational mapping), ORM see the big brother of the article to talk about Python Zhongyuan class Metaclass (two): ORM practice

4. Summary

  • In fact, by type () class created by the class definition
  • type(object_or_name, bases, dict)
  • If you want to create a behavior control classes, you need to specify when you create a class metaclass, once a metaclass is specified, will be added to the class __metaclass__, will find the time to create a class __metaclass__point of class and create a class with the class, if not, it invokes the default type ()

Reference article

In Python metaclass (metaclass)
talk about Python Zhongyuan class Metaclass (a): What is the metaclass
metaclass of Python

发布了62 篇原创文章 · 获赞 33 · 访问量 1万+

Guess you like

Origin blog.csdn.net/zjbyough/article/details/95667735