day7-类的起源与metaclass
一、类的起源
1 #coding:utf-8 2 3 # 创建一个Foo类 4 class Foo(object): 5 def __init__(self,name): 6 self.name = name 7 print("Foo __init__") 8 9 # 所有对象都是通过__new__方法来实例化,new方法里调用init方法 10 # 实例化过程执行顺序: new-->init 11 def __new__(cls, *args, **kwargs): 12 # 可以增加一些操作,最好不要轻易重构 13 print("Foo __new__",cls,args,kwargs) 14 cls.date = '2017-06-30' 15 # 然后继承父类的new方法 16 return object.__new__(cls) 17 18 print("-"*30+"1") 19 # 实例化对象f 20 f = Foo("lulu") 21 # 输出new方法定义的变量 22 print(f.date) 23 24 print("-"*30+"2") 25 # 输出:<class '__main__.Foo'>,f是由Foo类创建,即f是Foo类的一个实例 26 print(type(f)) 27 # 输出:<type 'type'>,Foo是由type类创建,即Foo是type类的一个实例 28 print(type(Foo)) 29 30 print("-"*30+"3") 31 # type创建类的格式,传入的父类必须为一个元组 32 # 类名 = type('类名',(父类,),{'方法名':方法的内存地址}) 33 34 # 定义一个func函数,如果是放入类的方法,则必须加上self参数 35 def func(self): 36 print("hello {0}".format(self.name)) 37 38 # 创建构造方法 39 def __init__(self,name): 40 self.name = name 41 42 # 通过type创建类 43 # 经典类写法: Foo = type("Foo",(),{"talk":func,"__init__":__init__}) 44 Foo = type("Foo",(object,),{"talk":func,"__init__":__init__}) 45 # 初始化对象 46 f = Foo("lulu") 47 f.talk() 48 49 50 >>> 51 ------------------------------1 52 ('Foo __new__', <class '__main__.Foo'>, ('lulu',), {}) 53 Foo __init__ 54 2017-06-30 55 ------------------------------2 56 <class '__main__.Foo'> 57 <type 'type'> 58 ------------------------------3 59 hello lulu
二、metaclass
1 #coding:utf=8 2 3 # 自定义一个类 4 class MyType(type): 5 # 第2步,调用元类的init方法 6 def __init__(self,*args,**kwargs): 7 8 print("Mytype __init__",args,kwargs) 9 10 # 第3步,调用元类的call方法 11 def __call__(self, *args, **kwargs): 12 print("Mytype __call__", args, kwargs) 13 # 这里调用Foo类的new方法 14 obj = self.__new__(self) 15 print("obj ",obj, args, kwargs) 16 print(self) 17 # 这里调用Foo类的init方法 18 self.__init__(obj, *args, **kwargs) 19 return obj 20 21 # 第1步,调用元类的new方法 22 def __new__(cls, *args, **kwargs): 23 print("Mytype __new__", args, kwargs) 24 # 此处调用type类的new方法,里面会调用init方法 25 return type.__new__(cls, *args, **kwargs) 26 27 # python3写法 28 # class Foo(object,metaclass=MyType) 29 class Foo(object): 30 # python2写法 31 # metaclass表元类,指定哪个类帮它完成实例化创建,此处指定自定制类MyType 32 # 元类的调用顺序:new-->init-->call 33 __metaclass__ = MyType 34 35 # 第5步,调用Foo类的init方法 36 def __init__(self,name): 37 self.name = name 38 39 print("Foo __init__") 40 41 # 第4步,调用Foo类的方法 42 def __new__(cls, *args, **kwargs): 43 print("Foo __new__",cls, args, kwargs) 44 return object.__new__(cls) 45 46 # 第一阶段:1,2步,解释器从上到下执行代码创建Foo类 47 # 第二阶段:3,4,5步,通过Foo类创建对象f 48 f = Foo('lulu') 49 50 51 >>> 52 ('Mytype __new__', ('Foo', (<type 'object'>,), {'__module__': '__main__', '__metaclass__': <class '__main__.MyType'>, '__new__': <function __new__ at 0x028AEAB0>, '__init__': <function __init__ at 0x028AEA70>}), {}) 53 ('Mytype __init__', ('Foo', (<type 'object'>,), {'__module__': '__main__', '__metaclass__': <class '__main__.MyType'>, '__new__': <function __new__ at 0x028AEAB0>, '__init__': <function __init__ at 0x028AEA70>}), {}) 54 ('Mytype __call__', ('lulu',), {}) 55 ('Foo __new__', <class '__main__.Foo'>, (), {}) 56 ('obj ', <__main__.Foo object at 0x0272EA30>, ('lulu',), {}) 57 <class '__main__.Foo'> 58 Foo __init__

浙公网安备 33010602011771号