如果你这样做
import gdbm
db = gdbm.open('foo', 'cs')
你得到的对象是:
<gdbm.gdbm at 0x7f0982b9aef0>
您现在可以通过以下方式在数据库中设置键和值:
db['foo'] = 'bar'
print db['foo']
我想在Twisted中使用它们,并为__getitem__
和__setitem__
创建一个返回延迟的包装器。但是,我注意到了一些特殊的东西:
In [42]: dir(db)
Out[42]: ['close', 'firstkey', 'has_key', 'keys', 'nextkey', 'reorganize', 'sync']
此对象没有__getitem__
和__setitem__
。尝试其中任何一个都会产生属性访问错误。然而,它的行为就像一本字典。这是什么类型的对象?
(我怀疑这是一个C扩展对象,但我觉得奇怪的是它有类似dict的访问方法,但没有__getitem__
和__setitem__
方法。指向Python文档的指针描述了这种行为会有所帮助。)
此外:如果您希望将它们包含在延迟中,您将如何获得对db.__getitem__
和db.__setitem__
的引用?我看到的唯一解决方案是将db包装在实用程序类中:
class Db:
def __init__(self, db):
self.db = db
def __getitem__(self, x):
return self.db[x]
...
但也许我错过了一些明显的东西?
答案 0 :(得分:3)
gdbm
确实是一个C模块;该对象实现了C-API mapping protocol。
使用函数指针查看source code PyMappingMethods
结构。
您可以使用operator.getitem()
来访问密钥:
>>> from operator import getitem
>>> db['foo'] = 'bar'
>>> getitem(db, 'foo')
'bar'
你可以将getitem()
包裹在functools.partial()
中,使其成为一个有效的可调用的一个参数:
>>> from functools import partial
>>> gi = partial(getitem, db)
>>> gi('foo')
'bar'
由于getitem
和partial
在C中实现,因此该组合将始终比自定义对象,函数或lambdas更快地包装访问。