Day28- metaclass, the underlying analysis of class, object generation control

Too hard too hard, I can not stand can not stand

Moto类

In front of nuclear power, this may be my loaded to force a relatively speaking, all back, I want to open installed.

First, we need to figure out what is the metaclass.

We know, in python, all things are subject, in fact, learned yuan before class, I really can not understand, I only know that such a concept, knows met yuan class, I realized the meaning of this concept.

We have a class, and then instantiate an object of this class to produce, is not it, that there is no thought, like how come, for yes, out of class, and that it has not thought about what happens inside operating?

In fact, he is also an object class, he is the object metaclasses, and metaclass instantiate an object that is out of the class! Now do not then the concept of an object is instantiated only limited by the type of thing out, and all things are subject, it is not it can feel a little bit?

Then metaclasses concept clearly, class metaclass is an instance of the class object. So metaclass is what look like?

print(type(dict))
print(type(list))
print(type(str))
print(type(object))

print(type(type))

<class 'type'>
<class 'type'>
<class 'type'>
<class 'type'>
<class 'type'>

We can see these types of classes are all kinds of type, and even the type itself, are the type class.

So basically identified, type, is the metaclass. And all classes are instantiated by its out, and then out of the instantiated class to instantiate an object.

Well, since the metaclass is the class, first class yuan how come? First, the chicken or the egg? The first metaclass is written in C language, I believe we all understand little fool who met exactly explain something, you can say is written in C. . . . .

I do not think about this, and he is the bottom of things.

the underlying principle of class analysis

We know that class + class name, will be constructed to the class, and by the one we know, in fact, we did not think so simple, in fact, is a meta-class instance of the class created this object.

In fact, it has gone through such a step.

Person=type('Person',(object,),dict)

The return value is a type of class, the Person receives this return value, so there will be called 'Person' class, assigned to the Person. You can use this Person to instantiate the various objects.

First we talk about the role of each parameter, the first argument, it is clear that the name of the class to be created, and the second is that class to inherit from the parent class, must be written in the form or a list of tuples, because you do not just inherit a class, and the third is the key, is a dictionary, then the dictionary what is written inside it? You recall that you create a class before time, is not to write a lot of property, which in many ways, this time these properties and methods, are all pushed to go inside this dict

l={}
exec('''
school='oldboy'
def __init__(self,name):
    self.name=name
def score(self):
    print('分数是100')
''',{},l)

exec method, a total of three parameters, the first is a string, the second is a global variable to store the dictionary, and the third is stored dictionary of local variables, we have to take that kind of stuff inside, so what we need is the third parameter, and then into the whole inside of the l, this effect exec, he just a string of the code block in the first position of the parameter, and then execute the code, generates various namespace and then there is the mapping between the namespace inside the third parameter l, l can say is kept inside the mapping relationship. So let's look at this print l.

{'school': 'oldboy', '__init__': <function __init__ at 0x0000016746FD1EA0>, 'score': <function score at 0x00000167471BD048>}

Sure enough, it is a repository mapping dictionary, and then we threw the dictionary's third parameter type

Person=type('Person',(object,),l)

Becomes the case, then here, it generated good class, we can use the Person class to instantiate an object of.

Sure some people have such a problem, why type square three parameters generates class, put a parameter is the return type.

img

See, he is such a source. We use this type of meta-class instance of a class, it invokes the init method of the type, which is so specific.

Controlled by generating class metaclass

We know that metaclass type, has written, we can not move, then we how to control the class generated by the metaclass it, we can write, write on their own, then the other kind of default yuan write into their own class metaclass enough.

Custom metaclass: to control the generated class: You can control the class name, parent class can inherit control of the control class name space

Custom metadata class must inherit type, write a class that inherits type, this class called metaclass

class Mymeta(type):
    # def __init__(self,*args,**kwargs):
    def __init__(self,name,bases,dic):
        # self 就是Person类
        # print(name)
        # print(bases)
        # print(dic)

So we write a meta class of the custom.

Do a little exercise

Exercise 1: unrestricted control class name must start with sb

class Mymeta(type):
    # def __init__(self,*args,**kwargs):
    def __init__(self,name,bases,dic):
        if not name.startswith('sb'):
            raise Exception('类名没有以sb开头')

For example, we instantiate a class

 class person(metaclass=Mymeta):
        name='nick'

We added a metaclass = Mymeta in parentheses class inside, which is designated his metaclass is our custom that class, instead of the default type. This time we name (i.e. own class name), bases (i.e. its parent class, there is no), and DIC (its code blocks) pass into custom init method metaclass, the following operations you will understand.

Exercise Two: class must add a comment

class Mymeta(type):
    # def __init__(self,*args,**kwargs):
    def __init__(self,name,bases,dic):
        if not self.__dict__['__doc__']:
            raise Exception('类里没有注释')

This is not to explain, the same reason

Process Control Yuan class by calling the class

This and above what difference does it?

Difference is that this is the detail

Call process control class, in fact, in control: generated object

How to achieve? With __call__ to achieve

For instance, we have to generate a new class begins with qssb, you can write decision logic in the call inside.

class Mymeta(type):
    def __call__(self, *args, **kwargs):
        obj=object.__new__(self)
        obj.__init__(*args, **kwargs)
        # print(obj.__dict__)
        if not obj.__class__.__name__.startswith('qssb'):
            raise Exception('类名没有以qssb开头')
        return obj
class Person(object,metaclass=Mymeta):
    school='oldboy'
    def __init__(self,name):
        self.name=name
    def score(self):
        print('分数是100')

p=Person('nick')
print(p.name)

I will not explain this code, I'm tired.

Because you instantiate out of p, calls Person (), so it will carry out his __call__ method metaclass, and there are calls in its own init, understand it. First we look at the new, in his brackets write the name of a class, you can instantiate an empty object. Then you understand

Look after the property has been metaclass

Property class search order: start with the class itself look ---> mro inheritance to the parent class to find ----> Yuan class to find their own definition of ---> type in ---> error

Object attribute search order: start with the object itself to find ---> class to find ---> mro inheritance to the parent class to find ---> error

End End, back pain

Guess you like

Origin www.cnblogs.com/chanyuli/p/11455247.html