【发布时间】:2012-02-29 16:02:17
【问题描述】:
什么时候应该使用 PersistentDict,什么时候应该使用 Folder?它们在更新、内部结构、性能等方面有什么区别?
【问题讨论】:
标签: python zodb repoze.bfg
什么时候应该使用 PersistentDict,什么时候应该使用 Folder?它们在更新、内部结构、性能等方面有什么区别?
【问题讨论】:
标签: python zodb repoze.bfg
PersistentMapping 只是 python dict 类型的实现(通过标准库 UserDict 基类),针对 ZODB 的持久性语义进行了调整;每次更改 mapping 时,它都不必在继承自 Persistent 的最近类上设置 _p_changed 标志。
Folder 是一个更丰富的类型,实现事件,与 Zope Web 界面 (ZMI) 集成,通过 Web 任意属性(带有类型验证的属性),Zope 权限管理,子项验证ids、导入/导出等。子项目文件夹作为属性存储在对象本身上,一些元数据存储在实例的私有字典中。
当您需要任何这些额外服务(授权、ID 验证等)时,请使用 Folder,否则请使用 PersistentMapping。在性能方面查找或存储项目不会有太大差异;一个是下面的直pythondict,另一个是存储项目的实例__dict__。
如果您正在寻找避免冲突,您应该查看BTrees,OOBTree 类基本上是一个持久映射,其中值存储在持久存储桶中,在大多数情况下避免冲突,并为其余部分提供冲突解决方案.
如果您想要Folder 语义和BTree 存储语义,请查看Products.BTreeFolder2,以及实现Folder 接口但将子对象存储在OOBTree 中而不是直接作为属性的附加组件实例。
【讨论】:
PersistentDict(现在称为PersistentMapping)是一个继承自UserDict.IterableUserDict和persistent.Persistent的类em>。
UserDict.IterableUserDict 是一个内置的 python 类,它模拟一个可迭代的字典,persistent.Persistent 是一个 Zope 类,它可以将自身的实例保存在ZODB。
所以 PersistentDict(或 PersistentMapping)基本上是一个字典,可以作为对象存储在 ZODB 中。
普通字典不能作为单独的对象存储在 ZODB 中。它们必须是从 persistent.Persistent 继承的某个类的属性。
PersistentDict 将其键和值存储在实际字典中(data 属性)。
PersistentDict 不能通过 ZMI 添加,我认为它主要用于您希望将字典直接存储在 zodb 中的特殊情况。
文件夹我猜你的意思是 zope.container.folder 中的文件夹。 Folder 将其子项存储在 OOBTree 对象中,该对象是一个可以容纳大量对象的容器。
如果您想要一个包含其他内容类型实例的容器,那么您应该使用文件夹。
文件夹具有 PersistentDict 没有的接口,并且某些适配器或其他组件可能需要这些接口才能工作。例如,ContainerModified 事件只会在文件夹被修改时触发,而不是 PersistentDict。如果您将 PersistentDict 用作通用文件夹,则可能会有各种类似的陷阱。
在性能方面,字典通常会更快,直到键空间变得非常大。然后天平向 OOBTree 倾斜。
【讨论】:
ConflictErrors的情况下同时修改PersistentDict的不同键吗?假设我有d={'a': [1, 2, 3], 'b': [5, 6, 7]},它们是PersistentDict 和PersistentList 实例。如果一个线程/进程执行d['a'].append(5),另一个执行del d['b'][2],并且他们都提交......那会是ConflictError吗? Folder 怎么样? (我要自己尝试一下,但首先还有其他事情要做,所以我想我不妨问问。)