2013-11-04 37 views
8

我正在使用python-spidermonkey,它在內部使用PyMapping_Check來確定被用作全局對象(在rt.new_context(全局)中)是否實現映射協議。 (這基本上是一個傳遞給python-spidermonkey的字典,因此javascript對python變量的訪問權限有限。)如何在Python中正確實現映射協議?

在Python中沒有官方定義可以找到映射協議,所以我一直在使用試驗和錯誤確定它裏面的內容。有官方參考嗎?

回答

14

collections.abc模塊定義了諸如Mapping,Sequence等等的接口。

通過繼承該模塊中的抽象基類,您將獲得某些方法的默認實現。因此,被認爲是Mapping,你的類定義應該是這個樣子:

class MyMapping(collections.abc.Mapping): 
    def __getitem__(self, item) 
    def __iter__(self) 
    def __len__(self) 

Mapping繼承會得到大多數dict的有用的方法你「免費」的實現:

  • __contains__
  • keys
  • items
  • values
  • get
  • __eq__
  • __ne__

如果這些默認方法的實現是低效與您的自定義的數據結構,你可以隨時與自己的版本覆蓋它們。


被認爲是一個MutableMapping,你的類的接口應該是這樣的:

class MyMutableMapping(collections.abc.MutableMapping): 
    def __getitem__(self, item) 
    def __setitem__(self, item) 
    def __delitem__(self, item) 
    def __iter__(self) 
    def __len__(self) 

MutableMapping繼承讓你「免費」所有的Mapping的方法的定義,再加上:

  • pop
  • popitem
  • clear
  • update
  • setdefault

如果你從頭「滾動你自己的」,不希望使用一個抽象基類,你應該嘗試定義全部以上方法,如果你想讓你的班級嚴格Liskov-替代dict

+0

這似乎是正確的,謝謝!我希望他們在該頁面的任何地方使用了關鍵字映射協議。 – Chris

+1

如果你知道你已經爲你的特定用途實現了足夠的映射協議,但是還不足以通過常規的映射檢查,你還可以使用'collections.Mapping.register(MyMappingLikeClass)'。 – Blckknght

+0

@Blckknght:什麼是「常規映射檢查」? –