您的位置:首页 > 编程语言 > Python开发

8.python之面相对象part.9(初识元类part.1)

2017-04-26 11:43 197 查看
初步认识元类
#本篇文章介绍的元类,以及type以python3以上版本为准。
一.关于元类的前言。

在python中,一切皆对象,当然,类也是一个对象。

class c1:
pass
obj1 = c1()
从上面这段例子可以看到,obj1是c1这个类创建出来的一个对象,obj1是由c1去产生的,如果按照前面的理论来理解,类也是一个对象,那么c1是由谁创建出来的呢?
#type函数可以查看类型,也可以用来查看对象的类,二者是一样的
print(type(obj1)) # 输出:<class '__main__.c1'> 表示,obj1 对象由c1类创建
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  python 元类