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__

 

posted @ 2017-06-30 17:56  不知所以  阅读(96)  评论(0)    收藏  举报