Python元类

时间:2009-03-06 14:06:27

标签: python metaclass

我一直在使用Python破解类:

def hack(f,aClass) :
  class MyClass(aClass) :
     def f(self) :
       f()
  return MyClass

A = hack(afunc,A)

对我来说这看起来很干净。它需要一个类,A,创建一个派生自它的新类,它有一个额外的方法,调用f,然后将新类重新分配给A.

这与Python中的元类黑客有何不同?使用元类对此有什么好处?

3 个答案:

答案 0 :(得分:5)

Python中类的定义是类型的实例(或类型的子类的实例)。换句话说,类定义本身就是一个对象。使用元类,您可以控制成为类定义的类型实例。

调用元类时,您可以完全重写类定义。您可以访问类的所有建议属性,它的祖先等。不仅仅是注入方法或删除方法,您可以从根本上改变继承树,类型以及几乎任何其他方面。您还可以将元类链接在一起,以获得非常动态且完全错综复杂的体验。

我认为真正的好处是,类的类型仍然是类的类型。在您的示例中,键入:

a_inst = A()
type(a_inst)

将显示它是MyClass的实例。是的,isinstance(a_inst, aClass)将返回True,但您引入了一个子类,而不是动态重新定义的类。区别可能是关键。

正如rjh指出的那样,匿名内部类也具有性能和可扩展性含义。元类只处理一次,并且是定义类的时刻,而不是再次处理。 API的用户也可以扩展您的元类,因为它没有包含在函数中,因此您可以获得一定程度的可扩展性。

这篇稍微陈旧的文章实际上有一个很好的解释,它将您在示例中使用的“函数修饰”方法与元类完全比较,并在该上下文中显示Python元类演变的历史记录:http://www.ibm.com/developerworks/linux/library/l-pymeta.html

答案 1 :(得分:1)

元类是类的类。 IMO,这里的家伙非常有用,包括一些用例。请参阅Stack Overflow问题 "MetaClass", "new", "cls" and "super" - what is the mechanism exactly?

答案 2 :(得分:1)

您也可以使用type callable。

def hack(f, aClass):
    newfunc = lambda self: f()
    return type('MyClass', (aClass,), {'f': newfunc})

我发现使用type进入元类世界的最简单方法。