Python 中的元类编程 - 理解继承的奥秘和实例创建
2007-03-29 12:10:53 来源:WEB开发网核心提示: 部分混淆是由于在 Smalltalk 的术语中 C.mm 被称为“ C 的类方法”,但 Python 类方法与这种叫法不同,Python 中的元类编程 - 理解继承的奥秘和实例创建(7),元方法“mm”可以从元类或类被调用,但不是不能从实例调
部分混淆是由于在 Smalltalk 的术语中 C.mm 被称为“ C 的类方法”,但 Python 类方法与这种叫法不同。
元方法“mm”可以从元类或类被调用,但不是不能从实例调用。类方法既可以从类中调用也可以从实例中调用(但不存在于元类中)。
清单 11. 调用元方法
>>> print M.mm(C)
I am a metamethod of C
>>> print C.mm()
I am a metamethod of C
>>> print c.mm()
[...]
AttributeError: 'C' object has no attribute 'mm'
>>> print C.cm()
I am a classmethod of C
>>> print c.cm()
I am a classmethod of C
另外,元方法是由 dir(M) 而不是 dir(C) 获得的,而类方法是由 dir(C) 和 dir(c) 获得的。
您只能通过在元类上调度(像 print 这样的内建包在后台完成这一步)来调用在类 MRO 中定义的元类方法:
清单 12. 有魔力的元类方法
>>> print C.__str__()
[...]
TypeError: descriptor '__str__' of 'object' object needs an argument
>>> print M.__str__(C)
This is class C
注意到这种调度冲突不只局限于魔法方法是重要的。如果我们通过增加一个属性 C.mm 来改变 C ,也会有同样的问题(不管这个名字是常规的方法、类方法、静态方法还是简单的属性都不例外):
清单13. 不具魔力的元类方法
>>> C.mm=lambda self: "I am a regular method of %s" % self.__class__
>>> print C.mm()
[...]
TypeError: unbound method <lambda>() must be called with
C instance as first argument (got nothing instead)
更多精彩
赞助商链接