使用工厂定义的 Zope 实用程序与使用组件定义的 Zope 实用程序有什么区别?

发布于 2024-08-19 07:10:36 字数 199 浏览 5 评论 0 原文

Zope 实用程序的 ZCML 注册可以接受组件或工厂,这有点令人困惑。

有什么区别?

It's a little confusing that ZCML registrations for Zope utilities can accept a component or a factory.

<utility component=".some.Class" />

versus

<utility factory=".some.Factory" />

What is the difference?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

寄意 2024-08-26 07:10:36

我认为@lennart-regebro 的回答可能无意中有点欺骗性。这是可以理解的,因为 zope 文档有点模糊。我认为以下是正确的解释,但我必须亲自测试才能确定。

组件和工厂注册中,每次后续调用 getUtility,在初始注册后,将返回相同的实例

不同之处在于,组件方法会将引用的对象注册为要返回的实用程序实例,而工厂方法将调用引用的对象并将结果存储为要返回的实用程序实例。

工厂示例

例如,如果您有一个如下定义的实用程序类;

class MyUtility(object):
    implements(IMyUtility)
    ...

注册它;

将在执行 zcml 时创建 MyUtility 的实例并存储它以供将来调用 getUtility 时使用;

> a = getUtility(IMyUtility)
> b = getUtility(IMyUtility)
> c = getUtility(IMyUtility)
> a is b is c
True

请注意,我们可以将工厂注册为函数而不是类,它只需在不带参数调用时返回您要使用的实用程序的实例即可。

组件示例

组件的等效示例是:

class MyUtility(object):
    implements(IMyUtility)
    ...

my_module_instance_of_utility = MyUtility()

注册它;

这或多或少相当于工厂示例。唯一的区别是,组件示例中返回的实例是在通过任何内容(包括注册机制)导入 my_module 时实例化的,而使用工厂时,实例是在执行 zcml 配置时实例化的,就在注册之前。在这两种情况下,对 getUtility 的后续调用都将返回相同的实例。

不要与 IFactory 混淆

这些都不能与 IFactory 混淆,IFactory 确实提供了一些东西,可以在每次需要时为您提供一个新实例,但 API 略有不同。有关这些内容的更多信息,请参阅此文档

I think @lennart-regebro's answer might be a little unintentionally deceptive. It's understandable as the zope docs are a little vague. I think below is the correct interpretation but I had to test it myself to be sure.

In both the component and the factory registration each subsequent call to getUtility, after an initial registration, will return the same instance.

The difference is that the component method will register the referenced object as the utility instance to be returned, where as the factory method will call the referenced object and store the result as the utility instance to be returned.

Factory Example

So for example if you have a utility class defined as thus;

class MyUtility(object):
    implements(IMyUtility)
    ...

registering it with;
<utility factory=".my_module.MyUtility"/>

will at the point the zcml is executed create an instance of MyUtility and store it for any future calls to getUtility;

> a = getUtility(IMyUtility)
> b = getUtility(IMyUtility)
> c = getUtility(IMyUtility)
> a is b is c
True

Note that we could have registered the factory to be a function instead of a class, it just has to be something that when called with no arguments returns the instance of your utility you want to use.

Component Example

An equivalent example with component is;

class MyUtility(object):
    implements(IMyUtility)
    ...

my_module_instance_of_utility = MyUtility()

registering it with;
<utility component=".my_module.my_module_instance_of_utility"\>

This is more or less equivalent to the factory example. The only difference is that the instance returned in the component example is instantiated when my_module is imported by anything (including the registration mechanism), where as when using a factory the instance is instantiated when the zcml config is executed, just before it's registered. In both cases subsequent calls to getUtility will return the same instance.

Not to be confused with IFactory

None of this is to be confused with IFactory which does provide something which can provide you a new instance each time it's asked for but with a slightly different API. See this document for more information about those.

梦开始←不甜 2024-08-26 07:10:36

工厂创建实用程序,而注册为组件的实用程序是一个实例。因此,如果您查找注册为组件的实用程序,您每次都会得到相同的对象。但如果它注册为工厂,您每次都会获得一个新实例。

A factory creates utilities, while a utility registered as a component is an instance. Hence, if you look up a utility registered as a component, you will get the same object back every time. But if it's registered as a factory, you'll get a new instance every time.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文