Python“ in”关键字引发KeyError

问题描述 投票:1回答:1

为了检查TodoistAPI类中是否存在键,我使用“ in”关键字。但是,它会导致KeyError

我隔离了代码片段,以检查究竟是什么原因导致了KeyError以及提供了哪些输入。

api = TodoistAPI(token)
api.sync()
print("id" in api.state["items"][0])

api.state["items"][0]包含:

Item({'assigned_by_uid': None,
 'checked': 0,
 'child_order': 0,
 'collapsed': 0,
 'content': 'example task',
 'date_added': '0',
 'date_completed': None,
 'day_order': 0,
 'due': {'date': '0',
         'is_recurring': True,
         'lang': 'de',
         'string': 'every day',
         'timezone': None},
 'has_more_notes': False,
 'id': 0,
 'in_history': 0,
 'is_deleted': 0,
 'labels': [0, 0],
 'parent_id': None,
 'priority': 1,
 'project_id': 0,
 'responsible_uid': None,
 'section_id': None,
 'sync_id': None,
 'user_id': 0})

我希望print(...)的输出是TrueFalse,但实际输出如下

Traceback (most recent call last):
File "/Users/path/to/file.py", line 11, in 
print("id" in applicationInterface.state["items"][0])
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/todoist/models.py", line 16, in __getitem__
return self.data[key]
KeyError: 0

Process finished with exit code 1

我还在Todoist Github存储库中创建了一个问题:https://github.com/Doist/todoist-python/issues/64

python todoist
1个回答
1
投票

最终,这是Todoist库中的错误。

首先,让我们想象一下这样的另一行:

item = api.state["items"][0]
print("id" in item)

这意味着当您编写"id" in item时,Python将在类中检查__contains__方法。 Item类确实定义了__contains__,但确实定义了__getitem__(通过其基数Model)。 根据Python语言参考,使用

对序列协议的后退],__getitem__ will be called评估__getitem__

我认为用于评估in的逻辑与此等效:

"id" in item

## Implicit logic used to evaluate `"id" in item`
for i in itertools.count():
    try:
        result = item[i]
    except IndexError:
        return False

    if result is "id" or result == "id":
        return True
return False
的求值内,引发KeyError。从根本上讲,如果Model.__getitem__是映射类型,则我认为它应该同时实现Model__contains____getitem__这样说:

建议映射和序列都实现Python data model方法,以允许有效使用__contains__()运算符;对于映射,in应该搜索映射的键
© www.soinside.com 2019 - 2024. All rights reserved.