初步认识元类python
#本篇文章介绍的元类,以及type以python3以上版本为准。python2.7
一.关于元类的前言。
ide
在python中,一切皆对象,固然,类也是一个对象。
函数
class c1:spa
passorm
obj1 = c1()对象
从上面这段例子能够看到,obj1是c1这个类建立出来的一个对象,obj1是由c1去产生的,若是按照前面的理论来理解,类也是一个对象,那么c1是由谁建立出来的呢?继承
#type函数能够查看类型,也能够用来查看对象的类,两者是同样的内存
print(type(obj1)) # 输出:<class '__main__.c1'> 表示,obj1 对象由c1类建立it
print(type(c1)) # 输出:<type 'type'>
也就是说咱们定义的类,所有都是由type产生的。
经过这个知识点,能够引出两种建立类的方式。
方式一:使用class关键字定义一个类。
class Foo:
def func(self):
print('from func')
方式二:经过type定义一个类。
def func(self):
print('from func')
x=1
Foo=type('Foo',(object,),{'func':func,'x':1})
二.什么是元类?
所谓的元类,能够理解为它是类的类,元类是去控制如何建立一个类的,就像类是对象的模版同样,元类则是类的模版。
type和元类由什么关系呢?
当一个类没有声明本身的元类时,这个类默认的元类就是type。
不止如此,用户还能够经过type来定义一个元类。
注意!当自定义元类的时候,本身定义的元类必定要继承type!
关于元类参数的剖析:
python2.7ver:
class mytype(type):
def __init__(self,class_name,bases,dict):
print "mytype __init__ runing!!"
print class_name #类的名字
print bases #继承的父类
print dict #类的名称空间字典(也就是类的__dict__)
print self #定义的类的本体(也就是类的内存地址)
class test_class(object): #将mytype做为元类,建立一个类,名为test_class
__metaclass__ = mytype #python2.7中指定元类的方法。
def running(self):
print "runing....."
接下来执行如下代码。
输出:
mytype __init__ runing!!
test_class
(<type 'object'>,)
{'__module__': 'test1', '__metaclass__': <class 'test1.mytype'>, 'running': <function running at 0x10e149c08>}
<class 'test1.test_class'>
python3.5ver:
class mytype(type):
def __init__(self,class_name,bases,dict):
print("mytype __init__ runing!!")
print(class_name) #类的名字
print(bases) #继承的父类
print(dict) #类的名称空间字典(也就是类的__dict__)
print(self) #定义的类的本体(也就是类的内存地址)
class test_class(metaclass = "mytype"): #将mytype做为元类,建立一个类,名为test_class
def running(self):
print("runing.....")
#从输出的结果能够看出,当咱们在建立一个类的时候,就会触发元类的__init__构造方法,就好像是用类建立对象的过程同样。
类是如何实例化出属性的呢?下面就经过元类手动来实现这个功能。
python2.7ver:
class mytype(type):
def __init__(self,class_name,bases,dict):
print "mytype __init__ runing!!"
print class_name
print bases
print dict
print self
def __call__(self, *args, **kwargs): # 当使用类去实例化一个对象的时候,类后面须要加()这就会触发元类中定义的__call__方法。
print "mytype call runing -----> %s,%s,%s" %(self,args,kwargs)
obje = self.__new__(self) #生成一个空的对象
self.__init__(obje,*args,**kwargs) #调用元类所建立类的构造方法。
return obje #将空对象返回
class test_class(object):
__metaclass__ = mytype
a = 1
def running(self):
print "runing....."
obj1 = test_class()
print obj1.a