Python metaclass , __new__, super()的粗略认识


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

未完待续。。。。。。。

转载于:https://my.oschina.net/u/2406653/blog/479493

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值