python进阶-面向对象编程六:元类
什么是元类
# typer===>produce class===>produce obj # type称谓元类,是所有类的类,利用type控制类的行为
模拟class关键字创建类的过程:类被创建的2种方法
# 模拟class关键字创建类的过程 # 创建类的两种方式 # 方式一: class Foo: def func(self): print('from func') # 方式二: x = 1 def func(self): print('from func') Foo=type('Foo',(object,),{'func':func,'x':1}) # 创建类的两种方式 # 方式一: class Foo: x=1 def run(self): pass print(type(Foo)) # <class 'type'> # 方式二: class_name="Bar" def Run(self): print("%s is running"%self.name) bases=(object,) class_dic={ "x":1, "run":Run } Bar=type(class_name,bases,class_dic) print(Bar) print(type(Bar)) print(type("123")) print(type(123)) # 运行结果: # <class '__main__.Bar'> # <class 'type'> # <class 'str'> # <class 'int'>
自定制一个元类,让它必需具有注释
# 元类,我们重定义的元类如果不写注释就暴错 class Mymeta(type): def __init__(self,class_name,class_bases,class_dic): for key in class_dic: if not callable(class_dic[key]):continue if not class_dic[key].__doc__: raise TypeError("all the func must be notes") class Foo(metaclass=Mymeta): x=1 def run(self): '所有函数必须写注释' print("class Foo") Foo().run()
创建元类的具体过程
# 一切皆对象,类也是对象,元类就是类的类 # type()内建函数可以创建类 class C(object): pass c=C() print(c) print(C) # <__main__.C object at 0x10d41fc18> # <class '__main__.C'> # type(类名, 父类的元组(可以为空), 属性的字典) def printinfo(self): print("%s age %s"%(self.name,self.age)) S = type("Student",(object,),{"name":'adamanter',"age":24,"printinfo":printinfo}) print(type(S)) s=S() print(type(s)) s.printinfo() # <class 'type'> # <class '__main__.Student'> # adamanter age 24 # 函数type实际上是一个元类,元类就是用来创建类的"模板"。 # 我们可以通过类"模板"创建实例对象,同样,也可以使用元类"模板"来创建类对象; # 也就是说,元类就是类的类. # 创建类的过程是,__new__,__init__,创建出类来进行实例化的过程是__call__ # python2 # 在创建一个类的时候,可以设置"__metaclass__"属性来指定元类。 # __metaclass__ = QueueMetaclass # 属性后面对应的就是创建类的代码,可以是函数,也可以是一个类 # 元类的查找就是根据__metaclass__属性一层层向父类查找,如果找不到就用type创建类对象 # python3: # class Hello(matacalss=QueueMetaclass): # pass def queueMeta(name, bases, attrs): attrs['InQueue'] = lambda self, value: self.append(value) def deQueue(self): if len(self) > 0: return self.pop(0) attrs['DeQueue'] = deQueue # 直接调用type内建函数 return type(name, bases, attrs) # 元类从`type`类型派生 class QueueMetaclass(type): def __new__(cls, name, bases, attrs): cls.name = name cls.bases = bases attrs['InQueue'] = lambda self, value: self.append(value) print("cls",cls) print("name",cls.name) print("bases",cls.bases) def deQueue(self): if len(self) > 0: return self.pop(0) attrs['DeQueue'] = deQueue # 直接调用type内建函数 # return type(name, bases, attrs) # 通过父类的__new__方法 return type.__new__(cls, name, bases, attrs) class MyQueue(metaclass=QueueMetaclass): # 设置metaclass属性,可以使用一个函数,也可以使用一个类,只要是可以创建类的代码 # __metaclass__ = queueMeta pass q = MyQueue() print(q) # 拦截类的创建 # 根据"__metaclass__"对应的代码修改类 # 返回修改之后的类 class MyMetaclass(type): def __new__(meta, name, bases, attrs): print('-----------------------------------') print("Allocating memory for class:", name) print(meta) print(bases) print(attrs) return super(MyMetaclass, meta).__new__(meta, name, bases, attrs) def __init__(cls, name, bases, attrs): print('-----------------------------------') print("Initializing class:", name) print(cls) print(bases) print(attrs) super(MyMetaclass, cls).__init__(name, bases, attrs) class MyClass(metaclass=MyMetaclass): def foo(self, param): pass myclass = MyClass() # ----------------------------------- # Allocating memory for class MyClass # <class '__main__.MyMetaclass'> # () # {'foo': <function MyClass.foo at 0x10757e620>, '__module__': '__main__', '__qualname__': 'MyClass'} # ----------------------------------- # Initializing class MyClass # <class '__main__.MyClass'> # () # {'foo': <function MyClass.foo at 0x10757e620>, '__module__': '__main__', '__qualname__': 'MyClass'}