Python“ in”关键字引发KeyError

时间:2019-10-27 15:06:24

标签: python todoist

为了检查import { switchMap } from 'rxjs/operators'; // ... ngOnInit() { this.activatedRoute.paramMap.pipe( switchMap((params) => this.service.getPlace(params.get('id'))) ).subscribe(res => { this.place = res; this.comments = res.comments; }); } 类中键的存在,我使用“ in”关键字。但是,它会导致TodoistAPI

我隔离了代码片段,以检查究竟是什么引起了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(...)True,但实际输出如下

False

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

1 个答案:

答案 0 :(得分: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使用序列协议的后备版本来评估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

Model.__getitem__的求值范围内,引发KeyError。从根本上讲,如果Model是映射类型,我认为它应该同时实现__contains____getitem__Python data model说:

  

建议映射和序列都实现__contains__()方法,以允许有效使用in运算符;对于映射,in应该搜索映射的键