[英]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.