python中元类是创建类对象的对象,这句话说着有点拗口。想了解元类首先我们要了解一下类,类是用来创建对象的一种规则。在Python中类也是一种对象。每种对象都是有类型的,那么类是属于哪种类型?
我们来做一下实验:
class A:
pass
a = A()
a.__class__ #<class '__main__.A'>,使用__class__属性或者使用type内建函数来查看他的类型
#既然说类也是对象,那么我们看看类的类型是什么
a.__class__.__class__ #<class 'type'>
#我们看看其他类的类型是不是也是type
type(1).__class__
type('a').__class__ #都是type,说明这些类的元类都是type
在上一篇文章中我们讲了type的几种用法,其中有创建类对象的方法。既然说元类是创建类对象的对象。那么我们就来创建一个使用元类的对象。
def metaFunc(name,parents,attrs):
print(name,parents,attrs)
return type(name,parents,attrs)
class A(metaclass=metaFunc):#python3中的写法,python2中使用__metaclass__属性来赋值元类
pass
A() #A () {'__module__':'__main__'.....}
上面是一个面向过程的,下面我们写另一种面向对象的写法
class MC(type):#继承type
def __new__(cls, name, parents, attrs):#重写new方法
return type.__new__(cls,name,parents,attrs)#调用父类new方法
class A(metaclass=MC):
pass
A()#这样我们在看A.__class__就会看到他的类型是<class '__main__.MC'>
下面我们说说元类的作用:
既然说元类是创建类对象的对象,那么就是说类对象还没有出现之前执行的元类。那么元类的作用就是在创建类对象时改造类对象的一种方式。
上文的__new__
方法简单来说一下,
我们都知道类在创建对象时常用的几个特殊方法,在对象声明周期中的几个特殊方法我们常用的有__init__
和__del__
。有这么一个方法__new__
他是在init之前执行的一个函数,它的定义__new__(cls,params...)
self换成类对象cls,剩下的params同init的参数,它必须有返回值,他的返回值是实例对象本身。
class A:
def __init__(self,name):
print("init",name)
def __new__(cls, name):
print("new",name)
return super(A,cls).__new__(cls)
'''
self会指向new返回的对象
'''