简体   繁体   English

Python 元类

[英]Python metaclasses

I've been hacking classes in Python like this:我一直在像这样在 Python 中破解课程:

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

A = hack(afunc,A)

Which looks pretty clean to me.这对我来说看起来很干净。 It takes a class, A, creates a new class derived from it that has an extra method, calling f, and then reassigns the new class to A.它需要一个 class, A,创建一个从它派生的新 class,它有一个额外的方法,调用 f,然后将新的 class 重新分配给 A。

How does this differ from metaclass hacking in Python?这与 Python 中的元类黑客攻击有何不同? What are the advantages of using a metaclass over this?与此相比,使用元类有什么优势?

The definition of a class in Python is an instance of type (or an instance of a subclass of type). Python 中 class 的定义是类型的实例(或类型的子类的实例)。 In other words, the class definition itself is an object.换句话说,class 定义本身就是 object。 With metaclasses, you have the ability to control the type instance that becomes the class definition.使用元类,您可以控制成为 class 定义的类型实例。

When a metaclass is invoked, you have the ability to completely re-write the class definition.调用元类时,您可以完全重写 class 定义。 You have access to all the proposed attributes of the class, its ancestors, etc. More than just injecting a method or removing a method, you can radically alter the inheritance tree, the type, and pretty much any other aspect.您可以访问 class 的所有建议属性、其祖先等。不仅仅是注入方法或删除方法,您还可以从根本上改变 inheritance 树、类型以及几乎任何其他方面。 You can also chain metaclasses together for a very dynamic and totally convoluted experience.您还可以将元类链接在一起,以获得非常动态且完全复杂的体验。

I suppose the real benefit, though is that the class's type remains the class's type.我想真正的好处是类的类型仍然是类的类型。 In your example, typing:在您的示例中,键入:

a_inst = A()
type(a_inst)

will show that it is an instance of MyClass .将显示它是MyClass的一个实例。 Yes, isinstance(a_inst, aClass) would return True , but you've introduced a subclass, rather than a dynamically re-defined class.是的, isinstance(a_inst, aClass)将返回True ,但您引入了一个子类,而不是动态重新定义的 class。 The distinction there is probably the key.那里的区别可能是关键。

As rjh points out, the anonymous inner class also has performance and extensibility implications.正如 rjh 所指出的,匿名内部 class 也具有性能和可扩展性影响。 A metaclass is processed only once, and the moment that the class is defined, and never again.一个元类只被处理一次,并且在 class 被定义的那一刻,永远不会再被处理。 Users of your API can also extend your metaclass because it is not enclosed within a function, so you gain a certain degree of extensibility. API 的用户也可以扩展您的元类,因为它没有包含在 function 中,因此您获得了一定程度的可扩展性。

This slightly old article actually has a good explanation that compares exactly the "function decoration" approach you used in the example with metaclasses, and shows the history of the Python metaclass evolution in that context: http://www.ibm.com/developerworks/linux/library/l-pymeta.html这篇稍微有点旧的文章实际上有一个很好的解释,它将您在示例中使用的“函数修饰”方法与元类进行了完全比较,并展示了 Python 元类在这种情况下演变的历史: http://www.ibm.com/developerworks /linux/library/l-pymeta.html

A metaclass is the class of a class.元类是 class 的 class。 IMO, the bloke here covered it quite serviceably, including some use-cases. IMO,这里的家伙很好地覆盖了它,包括一些用例。 See Stack Overflow question "MetaClass", " new ", "cls" and "super" - what is the mechanism exactly?请参阅 Stack Overflow 问题“MetaClass”、“ new ”、“cls”和“super”——具体的机制是什么? . .

You can use the type callable as well.您也可以使用可调用type

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

I find using type the easiest way to get into the metaclass world.我发现使用type是进入元类世界的最简单方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM