Python 中的元类编程(3)
2008-09-30 12:42:40 来源:WEB开发网出现错误比静静地覆盖显式的 _metaclass_ 钩子要好。因此,如果试图同时使用两个类初始化器,或者两次调用同一个类初始化器,将导致错误:
清单 10. 双重增强导致了一个问题
>>> class C:
... Enhance(a=1)
... Enhance(b=2)
Traceback (most recent call last):
...
SyntaxError: Don't use two class initializers or
a class initializer together with a__metaclass__ hook
从好的方面看,继承的 _metaclass_ 钩子和自定义元类的所有问题都被解决了:
清单 11. 有效地增强继承的元类
>>> class B: # a base class with a custom metaclass
... class __metaclass__(type):
... pass
>>> class C(B): # class with both custom metaclass AND class initializer
... Enhance(a=1)
>>> C.a
1
>>> type(C)
<class '_main.__metaclass__'>
类初始化器并没有干扰到 C 的元类,它继承了基类 B,并且继承的元类不但不会影响到类初始化器,而且会很好地运行。相反,如果试图在基类中直接调用 Enhance,则可能会遇到问题。
总结
使用所有这些定义的方法,自定义类初始化将变得更加简单和美观。可能就像下面的清单这么简单:
清单 12. 最简形式的增强
class _XO_plus(gnosis.xml.objectify._XO_):
Enhance(XPath=XPath, addChild=addChild, is_root=is_root)
gnosis.xml.objectify._XO_ = _XO_plus
这个例子仍然使用了“注入”,这对普通情况来说有些多余;也就是说,我们将增强的类放回到模块名称空间中的一个特定名称中。这对特定的模块是必要的,但是大多数时候都不需要。在任何情况下,Enhance() 的参数不需要像上面那样固定在代码中,您可以公平地对完全动态的事情使用 Enhance(**feature_set)。
更多精彩
赞助商链接