python基础_元类

元类:

元类是类的类,元类主要是控制类是如何创建的,正如类控制对象如何创建一样。

type是python的一个内建元类,用来直接控制生成类,python中任何class定义的类其实都是type类实例化的对象。

创建类的两种方式:

1.使用class关键字,

class Chinese(object):
    country='China'
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def talk(self):
        print('%s is talking' %self.name)

2.手动创建,利用type实例化

#法一
class Foo:
    def __init__(self):
        pass
print(Foo)
print(Foo.__dict__)

#法二:
def __init__(self,name,age):
    self.name=name
    self.age=age
def test(self):
    print('=====>')
FFo=type('FFo',(object,),{'x':1,'__init__':__init__,'test':test})
print(FFo)
print(FFo.__dict__)

f1=FFo('alex',18)
print(f1.name)
f1.test()

<class '__main__.Foo'>
{'__module__': '__main__', '__init__': <function Foo.__init__ at 0x00000168BA6456A8>, '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None}
<class '__main__.FFo'>
{'x': 1, '__init__': <function __init__ at 0x00000168BA042EA0>, 'test': <function test at 0x00000168BB67EEA0>, '__module__': '__main__', '__dict__': <attribute '__dict__' of 'FFo' objects>, '__weakref__': <attribute '__weakref__' of 'FFo' objects>, '__doc__': None}
alex
=====>

 type 接收三个参数:

  • 第 1 个参数是字符串 ‘Foo’,表示类名

  • 第 2 个参数是元组 (object, ),表示所有的父类

  • 第 3 个参数是字典,这里是一个空字典,表示没有定义属性和方法

补充:若Foo类有继承,即class Foo(Bar):.... 则等同于type('Foo',(Bar,),{})

自定义元类:

对象加括号,会默认执行产生该对象的类中的__call__方法。

class MyType(type):
    def __init__(self,a,b,c):
        print('初始化生成Foo类')
    def __call__(self, *args, **kwargs):
        obj=object.__new__(self)
        self.__init__(obj,*args,**kwargs)
        return obj
class Foo(metaclass=MyType):
    def __init__(self,name):
        self.name=name
        print('初始化生成Foo类对象')

初始化生成Foo类

class MyType(type):
    def __init__(self,a,b,c):
        print('初始化生成Foo类')
    def __call__(self, *args, **kwargs):
        obj=object.__new__(self)  #object.__new__(Foo)--->f1
        self.__init__(obj,*args,**kwargs)
        return obj
class Foo(metaclass=MyType):
    def __init__(self,name):
        self.name=name
        print('初始化生成Foo类对象')
f1=Foo('alex')

初始化生成Foo类
初始化生成Foo类对象

 第一次之所以打印:初始化生成Foo类,是因为在执行Foo类的__init__()时,触发了MyType的__init__()函数的内部命令执行,因为只有执行MyType的__init__()函数的内部命令,才算对MyType进行了实例化,才会有Foo这个类,才能执行它的__init__(),又是因为无需进行Foo实例化对象,所以无需执行Foo的__init__()内部的命令。

第二次之所以两句都打印了,是因为加了一句Foo实例化对象的语句。

加断点一句一句执行就会发现,在执行了f1=Foo('alex')之后转去执行了__call__()函数的内部,因为Foo是MyType的对象,所以Foo加上了()之后,要去执行所属类的__call__函数。

f1=object.__new__(Foo),Foo实例化化产生对象f1。

 

posted @ 2018-06-24 20:56  Liu呵呵  阅读(78)  评论(0编辑  收藏  举报