在讨论元类时, 文档 指出:
您当然也可以覆盖其他类方法(或添加新方法);例如,在元类中定义自定义
__call__()
方法允许在调用类时自定义行为,例如,并不总是创建一个新实例。
[编者注:这已从 3.3 的文档中删除。它在 3.2 中: 自定义类创建]
我的问题是:假设我想在类被调用时有自定义行为,例如缓存而不是创建新对象。我可以通过覆盖类的 __new__
方法来做到这一点。我什么时候想用 __call__
来定义元类?这种方法提供了什么 __new__
无法实现的?
原文由 Eli Bendersky 发布,翻译遵循 CC BY-SA 4.0 许可协议
您的问题的直接答案是:当您想要做的 不仅仅是 自定义实例创建时,或者当您想要将类的 作用 与其创建方式分开时。
请参阅我对 Creating a singleton in Python 的回答和相关讨论。
有几个优点。
它允许您将类的 作用 与其创建方式的细节分开。元类和类各负责一件事。
您可以在元类中编写一次代码,并使用它来自定义多个类的调用行为,而不必担心多重继承。
子类可以覆盖其
__new__
方法中的行为,但是__call__
在元类上甚至不必调用__new__
如果有设置工作,你可以在元类的
__new__
方法中进行,它只发生一次,而不是每次调用类时。如果您不担心单一责任原则,那么在很多情况下定制
__new__
也同样有效。但是还有其他用例必须在创建类时更早发生,而不是在创建实例时发生。当这些发挥作用时,元类就很有必要了。请参阅 Python 中元类的(具体)用例是什么? 对于很多很好的例子。