在ZOBD(python3.x)中,我希望能够将对象作为键存储在BTrees.OOBTree.OOBTree()
中。我尝试时遇到的错误示例(见注释):
from BTrees.OOBTree import OOBTree as Btree
class Test:
pass
bt=Btree()
t=Test()
bt[t]=None #TypeError: Object has default comparison
因此,我在某个地方读到,可能需要定义__eq__
来删除该错误,但是尽管这似乎修复了之前的问题,但它似乎导致了更多的问题。示例:
[编辑:应该注意的是,我在继承OOBTree(和TreeSet)时发现了一些问题。显然,它们没有正确保存;因此,这与继承Persistent不同,即使它们继承Persistent。]
^{pr2}$在BTree或OOBTree中使用对象作为键的正确方法是什么?我确实需要测试一下钥匙是否也存在。在
对于那些不知道的人来说,ZODB中的btree非常类似于为持久性而设计的可伸缩Python字典(它们应该可以使用比普通Python字典更多的键值对)。在
虽然Eliot Berriot的回答让我找到了我需要的答案,但我想我会把帮助我的完整答案贴出来,这样其他人就不必花额外的时间来解决问题了。(我要用第二人称自言自语。)
首先,不要继承OOBTree或OOTreeSet(这会导致问题)。让自己的继承类持久化,如果你想要像继承的OOBTree一样的东西,在里面放一个OOBTree或OOTreeSet(如果你想要的话,也可以定义使它看起来像字典或集合所需的方法)。在
如果你不需要为每一个对象都创建一个完整的树,那么你就不需要为每一个对象创建一个完整的树。您需要定义Eliot提到的方法,以及其他一些类似的方法(这些方法需要比较整数ID而不是对象本身);也就是说,定义类的这些方法,这些方法将生成OOBTree的键或包含在OOTreeSet中的对象:
__eq__
,__ne__
,__hash__
,__lt__
,__le__
,__gt__
,和__ge__
。但是,除非你在类中有一个持久的ID,否则我就不能把它作为一个ID来保存,因为我没有在类中保存一个ID。在其次,你需要确保如果你要把对象作为键,那么最好不要在同一个OOBTree中将字符串这样的东西也设为键,否则你会有神秘的问题(因为字符串与对象没有相同的ID系统)。它将比较字符串键和对象键,并导致错误,因为它们不是用来比较的。在
下面是python3.x代码的一个工作示例,它允许您将对象用作OOBTree中的键,并且允许您迭代OOBTree中的持久对象(并将它们用作键)。它还向您展示了如何保存和加载对象。在
抱歉,它有点长,但它应该能让你很好地了解它的工作原理:
我想this answer可以帮你解决问题。在
基本上,您必须在对象上重新实现三个方法:
__eq__
(相等性检查)__ne__
(不相等检查)__hash__
使对象真正可序列化为字典键相关问题 更多 >
编程相关推荐