Python 类Dict对象,不带_getitem,_setitem__

Python 类Dict对象,不带_getitem,_setitem__,python,twisted,gdbm,Python,Twisted,Gdbm,如果你这样做 import gdbm db = gdbm.open('foo', 'cs') 您得到的对象是: <gdbm.gdbm at 0x7f0982b9aef0> 我想使用Twisted中的这些,并为返回延迟的\uu getitem\uuuuuuuu和\uuuuuuu setitem\uuuuuuuu制作一个包装器。然而,我注意到了一些奇怪的事情: In [42]: dir(db) Out[42]: ['close', 'firstkey', 'has_key', 'ke

如果你这样做

import gdbm
db = gdbm.open('foo', 'cs')
您得到的对象是:

<gdbm.gdbm at 0x7f0982b9aef0>
我想使用Twisted中的这些,并为返回延迟的
\uu getitem\uuuuuuuu
\uuuuuuu setitem\uuuuuuuu
制作一个包装器。然而,我注意到了一些奇怪的事情:

In [42]: dir(db)
Out[42]: ['close', 'firstkey', 'has_key', 'keys', 'nextkey', 'reorganize', 'sync']
此对象没有
\uuuu getitem\uuuu
\uuuu setitem\uuuu
。尝试这两种方法之一会导致属性访问错误。然而,它的行为就像一本字典。这是什么东西

(我怀疑这是一个C扩展对象,但我觉得奇怪的是,它有类似dict的访问方法,但没有
\uuuu getitem\uuuuuuu
\uuuuuu setitem\uuuuu
方法。一个指向描述此行为的Python文档的指针会很有帮助。)

进一步:如果您想将
db.\uuuu getitem\uuuu
db.\uuuu setitem\uuuuu
的引用打包到一个延迟文件中,您将如何获取它们?我看到的唯一解决方案是将db包装在实用程序类中:

class Db:
    def __init__(self, db):
         self.db = db

    def __getitem__(self, x):
         return self.db[x]

    ...

但也许我遗漏了一些明显的东西?

gdbm确实是一个C模块;该对象实现了C-API

有关带函数指针的
PyMappingMethods
结构,请参阅

您可以使用访问密钥:

>>> from operator import getitem
>>> db['foo'] = 'bar'
>>> getitem(db, 'foo')
'bar'
您可以将
getitem()
包装到中,使其成为一个有效的可调用参数:

>>> from functools import partial
>>> gi = partial(getitem, db)
>>> gi('foo')
'bar'

由于
getitem
partial
是用C实现的,所以这个组合总是比自定义对象、函数或lambda更快地包装访问。

什么是“将它们包装在延迟中”?@Jean-PaulCalderone:我的意思是写一些精神的东西
类Db:def get(self,key):return deletothread(db.\uuu getitem\uuuu,key)
。性能在这里不是问题,但我很想知道您对以这种方式从Twisted访问gdbm的看法。根据我的经验,将语法结构(如
db[key]
)转化为隐式线程化(或其他复杂的长时间运行)操作导致的混乱程度超过了它的最终价值。此外,请记住,
\uuuu setitem\uuuu
甚至不允许返回值-因此表示线程中该操作完成的
延迟的
丢失(例如,您无法进行错误处理)@Jean-PaulCalderone:谢谢。是的,显式更好,我现在把它写成
d=db.set(key,value)
d=db.get(key)
。它在
内联回调
-ed函数中工作得很好,看起来也不错。
>>> from functools import partial
>>> gi = partial(getitem, db)
>>> gi('foo')
'bar'