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

初步认识元类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

相关文章
相关标签/搜索