[英]How to use zope.interface.directlyProvides with instances of build in types (dict, string, …)
我有一堆字典,我想用类型信息来注释,以便以后可以为它们获取适配器。 在以下示例中,失败的情况是我要执行的操作,另一种情况显示了有效的版本。 是否可以在不引入额外对象的情况下使第一个版本正常工作? 创建字典的代码很难更改,因此我正在寻找添加一些类型信息的最简单且非侵入性的方法。
from zope.interface import Interface, implements, directlyProvides
from zope.interface.registry import Components
registry = Components()
class IA(Interface):
pass
# this one fails
data = {}
directlyProvides(data, IA)
# this way it works
class X(dict):
pass
data = X()
directlyProvides(data, IA)
zope.interface
依赖于在各种对象和类上设置一些魔术属性的能力。 这是怎么回事
>>> class Dict(dict):
... pass
...
>>> getattr(Dict, '__provides__', None)
没有。 现在尝试做你所做的。
>>> from zope.interface import Interface, implements, directlyProvides
>>> class IA(Interface):
... pass
...
>>> data = Dict()
>>> directlyProvides(data, IA)
尝试再次抓住__provides__
>>> getattr(Dict, '__provides__', None)
<zope.interface.declarations.ClassProvides object at 0x7f133cab48d0>
内建类型失败的原因是,您实际上无法(通过标准方式)对任何内置属性设置属性。
>>> setattr(dict, '__provides__', None)
Traceback (most recent call last):
File "<console>", line 1, in <module>
TypeError: can't set attributes of built-in/extension type 'dict'
因此,如果您想在某些标准类型的实例上分配一些标记器接口,它将失败。 只需按原样对它们进行子类化,或创建实际对象,这比Zope组件体系结构设计用于的对象更多。
您不能使用接口信息来注释Python内置类型。 您根本无法添加所需的属性。
您可以为该类型注册适配器(这样就不会实现接口):
>>> from zope.interface.registry import Components
>>> from zope.interface import Interface
>>> registry = Components()
>>> class IA(Interface):
... pass
...
>>> data = {}
>>> registry.registerAdapter(lambda o: 'adapter from dict to IA', [dict], IA)
>>> registry.queryAdapter(data, IA)
'adapter from dict to IA'
不幸的是,您不能在某些情况下执行此操作:
>>> registry.registerAdapter(lambda o: 'adapter from data to IA', [data], IA)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/mj/Development/venvs/stackoverflow-2.7/lib/python2.7/site-packages/zope/interface/registry.py", line 186, in registerAdapter
required = _getAdapterRequired(factory, required)
File "/Users/mj/Development/venvs/stackoverflow-2.7/lib/python2.7/site-packages/zope/interface/registry.py", line 432, in _getAdapterRequired
raise TypeError("Required specification must be a "
TypeError: Required specification must be a specification or class.
这意味着,如果您确实必须改编特定的词典,那么您的选择将受到限制。 使用dict
的子类是一种解决方法。
但是,您必须真正询问适应词典是否是解决问题的最佳方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.