什么是元类
# 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'}