2012-02-29 24 views

回答

3

A PersistentMapping簡單地是針對ZODB的持久性語義而調整的python dict類型(通過標準庫UserDict基類)的實現;它可以節省每次更改mapping時,必須在離Persistent最近的類別上設置_p_changed標誌。

A Folder是一個更豐富的類型,實現事件,與Zope Web接口(ZMI)集成,通過Web的任意屬性(具有類型驗證的屬性),管理Zope權限,驗證子項ID ,導入/導出等。子項目文件夾作爲屬性存儲在對象本身上,一些元數據存儲在實例的私人字典中。

當您需要任何這些額外服務(權限委派,ID驗證等)時,請使用Folder,否則請使用PersistentMapping。明智地查找或存儲項目的性能差異不大;一個是下面的直蟒dict,另一個是存儲項目的實例__dict__

如果您正在尋找避免衝突,你應該看看BTrees,該OOBTree類基本上是一個持久的映射,其中值存儲在持續桶,避免在大多數情況下的碰撞,併爲其餘的提供解決衝突。

如果你想Folder語義與BTree存儲語義,看Products.BTreeFolder2和插件,實現了Folder接口,但店子對象的OOBTree而不是作爲屬性直接的實例。

2

PersistentDict(現稱爲PersistentMapping)是從UserDict.IterableUserDictpersistent.Persistent繼承的類。

UserDict.IterableUserDict是一個內置的Python類模擬可迭代的字典和persistent.Persistent是一個Zope類,使自身的實例被保存在ZODB。

因此,PersistentDict(或PersistentMapping)基本上是一個字典,可以作爲一個對象存儲在ZODB中。

普通字典不能作爲單獨的對象存儲在ZODB中。他們必須是繼承自persistent.Persistent某些類的屬性。

PersistentDict將其鍵和值存儲在實際字典中(數據屬性)。

無法通過ZMI添加PersistentDict,我認爲它主要用於您想直接在zodb中存儲字典的特殊情況。

隨着文件夾我想你指的是文件夾中zope.container.folder。 文件夾將它的子項存儲在OOBTree對象內,這是一個可容納大量對象的容器。

當您想要一個包含其他內容類型實例的容器時,則應該使用文件夾。

文件夾具有PersistentDict沒有的接口,並且某些適配器或其他組件可能需要這些接口才能工作。例如,ContainerModified事件只會在文件夾被修改時觸發,而不是PersistentDict。如果您將PersistentDict用作通用文件夾,則可能會出現各種類似的陷阱。

說到性能,字典通常會更快,直到密鑰空間變得非常大。然後這些刻度向OOBTree傾斜。

+0

我可以同時修改不帶'ConflictErrors'的'PersistentDict'的不同鍵嗎?假設我有'd = {'a':[1,2,3],'b':[5,6,7]},這些是PersistentDict和PersistentList實例。如果一個線程/進程執行'd ['a']。append(5)',另外一個執行'del d ['b'] [2]',並且它們都會提交..會是'ConflictError'嗎?怎麼樣一個'文件夾'? (我會自己嘗試,但有其他的事情要做,首先,我想我不妨問一下。) – Claudiu 2012-02-29 19:49:28

+1

忘掉任何「文件夾」的概念 - 你需要比較PersistentDict和OOBTree(比較和蘋果到一個蘋果,而不是水果沙拉)。在許多情況下,OOBTree應該具有更好的衝突解決方案,但IIRC對於小型映射,您可能在同一個桶中有兩個密鑰,從而消除了這一優勢。隨着映射變得越來越大 - 特別是如果您對插入的密鑰使用了一個很好的策略來平均分佈在桶中,我認爲您最大限度地減少了衝突的可能性。 – sdupton 2012-02-29 20:31:16

+1

我的看法:只是使用BTrees(可能是OOBTree),除了瑣碎或小的映射外,只是意識到keys()會返回一個迭代器,它可以是一個移動的目標並且更像iterkeys() - 這違反了在Python 2中工作的方式,並且在行爲上更接近於Python 3中的keys()(除了字典視圖和迭代器語義之外)。 – sdupton 2012-02-29 20:32:50

相關問題