8.python之面相对象part.9(初识元类part.1)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了8.python之面相对象part.9(初识元类part.1)相关的知识,希望对你有一定的参考价值。
初步认识元类
#本篇文章介绍的元类,以及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
本文出自 “reBiRTH” 博客,请务必保留此出处http://suhaozhi.blog.51cto.com/7272298/1919559
以上是关于8.python之面相对象part.9(初识元类part.1)的主要内容,如果未能解决你的问题,请参考以下文章
补8.python之面相对象part.7(类相关函数的补充)
8.python之面相对象part.8(__slots__属性)
8.python之面相对象part.2(特殊属性,类方法,静态方法)