首先谈一下,个人热爱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开始工作。
未完待续。。。。。。。