Python 使用工厂和组件定义的Zope实用程序之间有什么区别?

Python 使用工厂和组件定义的Zope实用程序之间有什么区别?,python,zope,zcml,zope.component,Python,Zope,Zcml,Zope.component,Zope实用程序的ZCML注册可以接受组件或工厂,这有点令人困惑 对 区别是什么?工厂创建实用程序,而注册为组件的实用程序是实例。因此,如果查找注册为组件的实用程序,每次都会返回相同的对象。但是如果它注册为工厂,你每次都会得到一个新的实例。我认为@lennart regebro的回答可能有点无意中的欺骗性。这是可以理解的,因为zope文档有点模糊。我认为下面的解释是正确的,但我必须亲自测试才能确定 在中,组件和工厂注册在初始注册后,对getUtility的每个后续调用都将返回相同的实例 不同

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


区别是什么?

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

我认为@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略有不同。参见。

@lennart regebro最后一句话应该是这样的?“…但是如果它注册为一个实用程序,你每次都会得到一个新实例。”@Maddy:不,相反。