类似于Dict的对象没有__getitem __,__ setitem__

时间:2013-10-06 23:38:40

标签: python twisted gdbm

如果你这样做

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]

    ...

但也许我错过了一些明显的东西?

1 个答案:

答案 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'

由于getitempartial在C中实现,因此该组合将始终比自定义对象,函数或lambdas更快地包装访问。