首先谈一下,个人热爱python,虽然是小白,但十分注重细节的理解和研究。以下是我个人最近的学习心得和代码调试反射出对python的一些理解。废话不说,测试代码:(python2.7)
class metaclasstest(type): def __new__(mcs, name, bases, dict): dict['foo'] = 'metaclasstest was here' return type.__new__(mcs, name, bases, dict) def __call__(self): print 'metaclass call' class B(object): def __new__(cls, *args, **kwargs): print 'B' return super(B, cls).__new__(cls, *args, **kwargs) def funB(self): print 'funB' class A(B): __metaclass__ = metaclasstest def q(self): pass def __new__(cls,*args, **kwargs): print 'A new' return super(A, cls).__new__(cls, *args, **kwargs) if __name__ == '__main__': print dir(type) print dir(metaclasstest) print dir(A) a = A() print a print a.foo print 'begin'
结果: ['__abstractmethods__', '__base__', '__bases__', '__basicsize__', '__call__', '__class__', '__delattr__', '__dict__', '__dictoffset__', '__doc__', '__eq__', '__flags__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__instancecheck__', '__itemsize__', '__le__', '__lt__', '__module__', '__mro__', '__name__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasscheck__', '__subclasses__', '__subclasshook__', '__weakrefoffset__', 'mro'] ['__abstractmethods__', '__base__', '__bases__', '__basicsize__', '__call__', '__class__', '__delattr__', '__dict__', '__dictoffset__', '__doc__', '__eq__', '__flags__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__instancecheck__', '__itemsize__', '__le__', '__lt__', '__module__', '__mro__', '__name__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasscheck__', '__subclasses__', '__subclasshook__', '__weakrefoffset__', 'mro'] ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__metaclass__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'foo', 'funB', 'q'] metaclass call None Traceback (most recent call last): File "/home/henry/test_workspace/test/metaclass.py", line 29, in <module> print a.foo AttributeError: 'NoneType' object has no attribute 'foo'
可以看到我在元类中加了一个__call__()方法,程序运行的结果让我十分高兴,对他报错了!
按道理到我们调用a = A()时按理会调用类A 的__new__ () ,结果是没有。原因在于:A 是基于metaclass的类,他是metaclass的实例,所以实力A会调用他的绑定的__call__方法。
那么我们因该如何生产A的实例呢?
方法是元类中不去覆盖type元类的__call__方法。(或者显式的调用super(metaclass, cls).__call__())
我的猜测(没去看type的源码):type元类的call方法会去帮助我们调用A的new方法,生产A的实例。
总结:
个人浅漏的认识(希望大牛拍砖): 当我们使用元类时,善用super,super没有产生一个父类对象,而是一个代理,这种代理让我们有资格去调用只有对象才能调用的绑定方法。而但python解释器运行有metaclass的模块时,他会首先去组装类,方式是:先把当前类的所有属性依次扫描(不包括父类)。然后将这些熟悉以类词典的方式传给metaclass,metaclass开始工作。
未完待续。。。。。。。