Python 元类与类装饰器
Python 元类和类装饰器之间的主要区别是什么?有什么事情我可以用其中一个来做,但不能用另一个来做吗?
What are the main differences between Python metaclasses and class decorators? Is there something I can do with one but not with the other?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
装饰器要简单得多,也更受限制——因此,只要可以使用元类或类装饰器实现所需的效果,装饰器就应该是首选。
您可以使用类装饰器执行的任何操作,当然也可以使用自定义元类执行(只需应用“装饰器函数”的功能,即在元类的 < 过程中采用类对象并修改它的功能) code>__new__ 或
__init__
生成类对象!-)。你可以在自定义元类中做很多事情,但不能在装饰器中做(当然,除非装饰器在内部生成并应用自定义元类 - 但这是作弊;-)...即使如此,在 Python 3 中,也有这些事情你只能用自定义元类来做,而不是事后做……但这是你的问题的一个相当高级的子领域,所以让我给出更简单的例子)。
例如,假设您想要创建一个类对象
X
以便print X
(或者当然在 Python 3print(X)
中;- ) 显示peekaboo!
。如果没有自定义元类,您不可能做到这一点,因为元类对 __str__ 的重写是这里的关键角色,即您需要一个def __str__(cls): return "peekaboo!" 在类
X
的自定义元类中。这同样适用于所有魔法方法,即应用于类对象本身的所有类型的操作(与应用于其实例的操作相反,实例使用类中定义的魔法方法 - - 对类对象本身的操作使用元类中定义的魔术方法)。
Decorators are much, much simpler and more limited -- and therefore should be preferred whenever the desired effect can be achieved with either a metaclass or a class decorator.
Anything you can do with a class decorator, you can of course do with a custom metaclass (just apply the functionality of the "decorator function", i.e., the one that takes a class object and modifies it, in the course of the metaclass's
__new__
or__init__
that make the class object!-).There are many things you can do in a custom metaclass but not in a decorator (unless the decorator internally generates and applies a custom metaclass, of course -- but that's cheating;-)... and even then, in Python 3, there are things you can only do with a custom metaclass, not after the fact... but that's a pretty advanced sub-niche of your question, so let me give simpler examples).
For example, suppose you want to make a class object
X
such thatprint X
(or in Python 3print(X)
of course;-) displayspeekaboo!
. You cannot possibly do that without a custom metaclass, because the metaclass's override of__str__
is the crucial actor here, i.e., you need adef __str__(cls): return "peekaboo!"
in the custom metaclass of classX
.The same applies to all magic methods, i.e., to all kinds of operations as applied to the class object itself (as opposed to, ones applied to its instances, which use magic methods as defined in the class -- operations on the class object itself use magic methods as defined in the metaclass).
正如《Fluent Python》一书第 21 章所述,其中一个区别与继承有关。请看这两个脚本。 python版本是3.5。一点是,元类的使用会影响其子类,而装饰器仅影响当前类。
该脚本使用类装饰器来替换/覆盖方法“func1”。
该脚本使用元类来替换/覆盖方法“func1”。
As given in the chapter 21 of the book 'fluent python', one difference is related to inheritance. Please see these two scripts. The python version is 3.5. One point is that the use of
metaclass
affects its children while the decorator affects only the current class.The script use class-decorator to replace/overwirte the method 'func1'.
The script use metaclass to replace/overwrite the method 'func1'.