使用元类的__call__方法而不是__new__? [英] Using the __call__ method of a metaclass instead of __new__?

查看:92
本文介绍了使用元类的__call__方法而不是__new__?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在讨论元类时,文档状态:

您当然也可以覆盖其他类方法(或添加新方法 方法);例如在 当调用类时,元类允许自定义行为,例如不是 总是创建一个新实例.

我的问题是:假设我想在调用类时具有自定义行为,例如缓存而不是创建新对象.我可以通过重写该类的__new__方法来做到这一点.什么时候我想用__call__定义元类呢?这种方法提供了什么,而这是__new__无法实现的?

解决方案

问题的直接答案是:当您要做的不仅仅是自定义实例创建时,更多,还是当您想分开类的创建方式.

请参阅我对在Python中创建单例的答案和相关的讨论. /p>

有几个优点.

  1. 它使您可以将类的作用与创建方式的细节分开.元类和类分别负责一件事.

  2. 您可以在元类中编写一次代码,并将其用于自定义几个类的调用行为,而不必担心多重继承.

  3. 子类可以在其__new__方法中重写行为,但是在元类上的__call__甚至根本不需要调用__new__.

  4. 如果有设置工作,则可以在元类的__new__方法中进行,并且仅发生一次,而不是每次调用该类时都会发生.

当然,在很多情况下,如果您不担心单一责任原则,自定义__new__也会同样有效.

但是,还有其他一些用例必须在更早的时候发生,即创建类时,而不是创建实例时.当这些元素发挥作用时,就必须要有一个元类.请参见元数据类的(具体)用例是什么中有很多很棒的例子.

When discussing metaclasses, the docs state:

You can of course also override other class methods (or add new methods); for example defining a custom __call__() method in the metaclass allows custom behavior when the class is called, e.g. not always creating a new instance.

My questions is: suppose I want to have custom behavior when the class is called, for example caching instead of creating fresh objects. I can do this by overriding the __new__ method of the class. When would I want to define a metaclass with __call__ instead? What does this approach give that isn't achievable with __new__?

解决方案

The direct answer to your question is: when you want to do more than just customize instance creation, or when you want to separate what the class does from how it's created.

See my answer to Creating a singleton in Python and the associated discussion.

There are several advantages.

  1. It allows you to separate what the class does from the details of how it's created. The metaclass and class are each responsible for one thing.

  2. You can write the code once in a metaclass, and use it for customizing several classes' call behavior without worrying about multiple inheritance.

  3. Subclasses can override behavior in their __new__ method, but __call__ on a metaclass doesn't have to even call __new__ at all.

  4. If there is setup work, you can do it in the __new__ method of the metaclass, and it only happens once, instead of every time the class is called.

There are certainly lots of cases where customizing __new__ works just as well if you're not worried about the single responsibility principle.

But there are other use cases that have to happen earlier, when the class is created, rather than when the instance is created. It's when these come in to play that a metaclass is necessary. See What are your (concrete) use-cases for metaclasses in Python? for lots of great examples.

这篇关于使用元类的__call__方法而不是__new__?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆