设置异常时避免递归

Avoiding recursion when setting exceptions

我正在尝试做一些相对简单的事情 - 使用 OrderedDict class 并赋予它基于整数或切片查找值的能力。所以如果我有以下

from collections import OrderedDict

test_dict = OrderedDict()
test_dict['a'] = 'value a'
test_dict['b'] = 'value b'
test_dict['c'] = 'value c'

test_dict[:2]

理想情况下会给出结果

['value a','value b']

为此,我正在尝试 subclass OrderedDict 然后覆盖它的 getitem 方法。我有以下内容:

class indexed_dict(OrderedDict):
    def __init__(self):
        pass

    def __getitem__(self, key):
        try:
            return list(self)[key]
        except TypeError: # Because we've entered a number instead of a key
            return self[key]

问题在于,如果您尝试正常使用它 - 比如说,test_indexed_dict['a'] - 解释器开始递归,大概是因为 except 子句要求它 运行 getitem 再次。有没有更好的错误处理方法不会产生这个问题?

在此先感谢您的帮助。

您可以检查 key 的类型,也可以检查 return 字典 的切片:

from collections import OrderedDict
class IndexedDict(OrderedDict):
    def __init__(self):
        pass

    def __getitem__(self, key):
        if type(key) is slice:
          return list(self.values())[key]
        else:
            return super().__getitem__(key)

这里有一个live example

当您执行 self[key] 时,您将再次调用自己的 __getitem__ 方法。这导致无休止的递归。你想要做的是调用你的 parent class's __getitem__ 方法:

def __getitem__(self, key):
    try:
        return list(self)[key]
    except TypeError: # Because we've entered a number instead of a key
        return super().__getitem__(key)

除了@Aran_Fey的回答,你还需要先检查 try 中的值,所以函数是:

def __getitem__(self, key):
    try:
        return list(self.values())[key]
    except TypeError:
        return super().__getitem__(key)

和整个class:

class IndexedDict(OrderedDict):
    def __init__(self):
        pass

    def __getitem__(self, key):
        try:
            return list(self.values())[key]
        except TypeError:
            return super().__getitem__(key)

@Netwave 的回答无法添加任何内容。