元类言简意赅版解释

元类言简意赅版解释

class mymeta(type):  ## 自定义元类
    
    ## 自定义元类的init方法是用来控制类的生成的
    def __init__(self,name,base,dict): 
        if  name.startswith('a'):
            raise Exception('不能以a开头')
    
    ## 这个new方法,是用来给type调用的,因为下面的class mycls的时候,就会调用他的元类也就是 mymeta(name,bases,dict),这里就变成了 mymeta加括号,就会调用type的call方法,type的call方法会调用self.__new__,也就是调用了下面的这个new方法,如果没有写这个方法,那就会调用type自身的new,下面的方法也是调用type的new,这里生成的对象是一个类,这个类已经初始化完成了。可以在下面这个__new__方法里面改变类的属性。
    def __new__(cls, *args, **kwargs):
        obj = type.__new__(cls, *args, **kwargs)
        return obj
	
    ## 这个call方法,是由mymeta类生成的类实例化对象的时候调用的,用来控制类实例化对象的过程。总之call 方法就是用来控制自己生成的类实例化对象的时候用的。
    def __call__(self, *args, **kwargs):
        obj = object.__new__(self)
        obj.__init__(*args, **kwargs)
        if obj.name == 'chanyuli':
            print('yes')
        return obj

class mycls(metaclass=mymeta):
    def __init__(self,name):
        self.name = name

cls = mycls('chanyuli')

print(cls.name)
class mymeta(type)
## 这行代码是一个自定义元类,既然他是一个类,他也是被实例化的,所以他也会调用 type(mymeta,type,dict),又要调用type的元类的call方法,type的元类是他自己,也就是说最后还是调用了type的call方法,是用C语言写的,但是内容至少也要做三步,
class type:
	def __call__(self, *args, **kwargs): # self=<class '__main__.
        # Mymeta'>
		obj=self.__new__(self,*args,**kwargs) # 产生Mymeta的一个对象
		self.__init__(obj,*args,**kwargs) # 初始化类
		return obj

看到最后想到奇怪的问题,上面这个不就是正常情况下自定义一个类吗???
和下面这一毛一样啊
class lalalal()
只不过没有去控制他的生成过程而已。
posted @ 2020-02-04 15:03  chanyuli  阅读(129)  评论(0编辑  收藏  举报