簡體   English   中英

如何使用zope.interface.direct提供內置類型實例(dict,string等)

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM