9.3 day29

What is the metaclass

In python, everything is an object, then certainly a class of an object

If the class is an object, then he must get by an instance of this class is called metaclass. That generated class class, called the metaclass

class Person:
    def __init__(self,name):
        self.name=name
    def score(self):
        print('分数是100')

p=Person('nick')

# a=Person
# p1=a('nick')
# print(p1.name)

#如何找元类?
# print(type(p))
#同理:type类是产生所有类的元类
# print(type(Person))
print(type(dict))
print(type(list))
print(type(str))
print(type(object))

print(type(type))

The above-described structures is <class 'type'>, that is to say, in general, the meta class type. built-in type is a metaclass, all classes are obtained with a type instantiation

the underlying principle of class analysis

class + class name, class will constructed, however, it is actually produced metaclass instantiate the object class.

We also can type directly produce class instead of the class keyword

type () __init__ Method out with class
type (object_or_name, bases, dict)
object_or_name: class name, a string of
bases: all of its parent class, the base class
dict: name space ,

Then we can define a simple Person class

def __init__(self,name):
    self.name=name
Person=type('Person',(object,),{'school':'oldboy','__init__':__init__})

We can also be achieved with the last dictionary exec () method of input

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

Controlled by generating class metaclass

Custom metaclass to control the production of class, you can control the class name, you can control inherit the parent class, custom metaclass control class name space must inherit type, and then produce class by a custom class, this custom class call metaclass

class Mymeta(type):
    # def __init__(self,*args,**kwargs):
    def __init__(self,name,bases,dic):
        # self 就是Person类
        # print(name)
        # print(bases)
        # print(dic)
        #练习一:加限制 控制类名必须以sb开头
        if not name.startswith('sb'):
            raise Exception('类名没有以sb开头')
class sb_Person(object,metaclass=Mymeta):

    school='雄英高中'
    def __init__(self,name):
        self.name=name
    def score(self):
        print('分数是100')

If the above code is the class name does not begin with sb, it is thrown 'class name does not begin with SB' abnormal

Similarly, we can also add comments to the class must make do

** method to query the comment class name .__ doc __ **

class Mymeta(type):
    def __init__(self,name,bases,dic):
        print(self.__dict__['__doc__'])
        doc=self.__dict__['__doc__']
        if not doc:
            # 没有加注释
            raise Exception('你的类没有加注释')
#metaclass=Mymeta  指定这个类生成的时候,用自己写的Mymeta这个元类
class Person(object,metaclass=Mymeta):
    '''
    注释
    '''
    school='音乃木坂学院'
    def __init__(self,name):
        self.name=name
    def score(self):
        print('分数是100')

Call process control class

Call process control class is actually produced in the control object

We use __call__ time, if the object plus (), it would call the class method __call__

So if we use the class add () when it? Obviously we will call the Yuan class method of __call__

Therefore, we can not change things in the class, the only class to class yuan in the Properties Hide

class Mymeta(type):
    def __call__(self, *args, **kwargs):
        obj=object.__new__(self)
        # self.__init__(obj,*args, **kwargs)    # 也可以用
        obj.__init__(*args, **kwargs)
        # print(obj.__dict__)
        obj.__dict__={ '_%s__%s'%(self.__name__,k):v for k,v in obj.__dict__.items()}
        # print(obj.__dict__)
        return obj

class Person(object, metaclass=Mymeta):
    school = 'oldboy'
    def __init__(self, name):
        self.name = name
    def score(self):
        print('分数是100')
p = Person(name='nick')
print(p.__dict__)
# print(p.name) # 会报错,因为已经被隐藏

After the property has metaclass search order

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 property search order: start with the object itself to find ---> class to find ---> mro inheritance to the parent class to find ---> error

class Mymeta(type):
    n=444

    def __call__(self, *args, **kwargs): #self=<class '__main__.OldboyTeacher'>
        obj=self.__new__(self)
        # print(self.__new__ is object.__new__) #True
        obj.__init__(*args, **kwargs)
        return obj


class Bar(object):
    # n=333
    pass

    # def __new__(cls, *args, **kwargs):
    #     print('Bar.__new__')

class Foo(Bar):
    # n=222
    pass

    # def __new__(cls, *args, **kwargs):
    #     print('Foo.__new__')

class OldboyTeacher(Foo,metaclass=Mymeta):
    # n=111

    school='oldboy'

    def __init__(self,name,age):
        self.name=name
        self.age=age

    def say(self):
        print('%s says welcome to the oldboy to learn Python' %self.name)

Guess you like

Origin www.cnblogs.com/hyc123/p/11454384.html