【问题标题】:in protocol with regard to sequence在关于序列的协议中
【发布时间】:2009-12-01 03:09:22
【问题描述】:

这是如何在 python 级别实现的?

我有一个在大多数情况下伪装成 dict 的对象(回想起来,我应该只是将 dict 子类化,但我宁愿不重构代码库,而且我也想知道这一点以备不时之需参考),看起来有点像

class configThinger(object):
    _config = {}
    def __getitem__(self, key):
        return self._config[key]
    def __setitem__(self, key, value):
        self._config[key] = value

当我尝试以 configThingerInstance['whatever'] 的形式访问它的元素时,它的工作原理和行为正确无误

但是像这样的电话

t = configThinger()
t.populate() # Internal method that fills it with some useful data
if 'DEBUG' in t:
    doStuff()

导致 KeyError 被引发,因为可能是 `in' 协议对有问题的键进行 getitem() 查找。我是否需要提出其他一些例外来说明它不存在? 我宁愿不做这样的事情。

try:
    t['DEBUG']
except KeyError:
    pass
else:
    doStuff()

另外,文档在哪里?

我四处张望

http://docs.python.org/tutorial/datastructures.html

http://docs.python.org/library/stdtypes.html

但可悲的是,试图用谷歌搜索特定于“in”这个词的东西是愚蠢的:(

编辑 1:

通过一堆跟踪打印,我可以看到程序调用了 configThingerInstance。getitem(0)

然而

t = {'rawk': 1,
     'rawr': 2,
    }
t[0] # Raises KeyError
'thing' in t # returns False

【问题讨论】:

  • @Richo,你所观察到的是对既不定义 __contain__ 也不定义 __iter__ 的类型的绝望的最后尝试(它试图看看它们是否可能是可迭代的恐惧说出那个名字;-)。
  • 我有一种预感,那就是它,这就是我开始寻找文档的地方,然后在这里问,而不是摸索着试图找到圭多留下的一些复活节彩蛋;)

标签: python protocols


【解决方案1】:

听起来你想重载 in 运算符?

您可以通过定义方法__contains__http://docs.python.org/reference/datamodel.html#object.contains来做到这一点

【讨论】:

    【解决方案2】:

    为了更好地支持in 运算符(遏制又名成员检查),请在您的configThinger 类上实现__contains__ 特殊方法:

    class configThinger(object):
        _config = {}
        def __getitem__(self, key):
            return self._config[key]
        def __setitem__(self, key, value):
            self._config[key] = value
        def __contains__(self, key):
            return key in self._config
    

    文档是 here(还解释了支持 in 运算符的其他次要方法)。

    【讨论】:

      猜你喜欢
      • 2010-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-19
      • 2018-06-07
      • 2010-12-07
      相关资源
      最近更新 更多