【发布时间】:2022-01-03 02:16:48
【问题描述】:
考虑x.py中的以下代码
from typing import Dict, List, Union
def _func2(do_something: bool) -> Dict[str, Dict[str, Union[str, List[str]]]]:
dict1: Dict[str, Union[str, List[str]]] = dict()
dict2: Dict[str, Union[str, List[str]]] = dict()
dict3: Dict[str, Union[str, List[str]]] = dict()
if (do_something):
dict1['key1'] = 'string1'
if ('key1' not in dict2.keys()):
dict2['key1'] = list()
assert(isinstance(dict2['key1'], list))
dict2['key1'].append('otherstring')
return {'outer_key_1': dict1, 'outer_key_2': dict2, 'outer_key_3': dict3}
def _func1(do_something: bool) -> Dict[str, Dict[str, Union[str, List[str]]]]:
dict1: Dict[str, Union[str, List[str]]] = dict()
dict2: Dict[str, Union[str, List[str]]] = dict()
dict3: Dict[str, Union[str, List[str]]] = dict()
keys: List[str] = ['key1']
if (do_something):
dict1['key1'] = 'string1'
if (keys[0] not in dict2.keys()):
dict2[keys[0]] = list()
assert(isinstance(dict2[keys[0]], list))
dict2[keys[0]].append('otherstring')
return {'outer_key_1': dict1, 'outer_key_2': dict2, 'outer_key_3': dict3}
命令mypy --strict --show-error-codes x.py显示
x.py:27: error: Item "str" of "Union[str, List[str]]" has no attribute "append" [union-attr]
Found 1 error in 1 file (checked 1 source file)
注意:_func2 和 _func1 的唯一区别是,_func1 中的键是字符串列表的一部分,而不是直接的字符串。
代码在运行时是可运行的——当然,如果函数被调用——但如果我需要使用 _func1(代码示例中的列表是静态的,在现实生活中不是),我如何满足 mypy?
【问题讨论】:
-
你可以通过设置
x = dict[keys[0]]; assert isinstance(x, list); x.append(...)来解决这个问题——虽然它很笨重,所以我将它作为评论留下,希望有人能用更惯用/优雅的东西来回答。 -
你能把这段代码删减一点吗?即使看了一会儿,我也不确定哪些部分是相关的,以及 MyPy(据说)在哪里旅行。我是否正确地认为更改归结为使用 literal
'key1'与 dynamickeys[0]?这三个 dicts 是否相关,或者一个就足够了? -
嗨@MisterMiyagi,你读过我的“笔记”吗?我认为这很好地解释了它,不是吗?如果您将代码复制到 python 文件并使用我包含的命令运行 mypy,您会看到第 27 行在哪里......我真的不明白如何让这更容易理解,抱歉。
-
您绝对可以删除
dict1、dict3和do_something。if (... not in dict2.keys()):似乎也是多余的——你可以直接将dict2初始化为{'key1': []}。您还可以删除所有布尔检查的非惯用括号,尽管在上次清理后只有assert会保留。 That cuts the function size easily in half.
标签: python-3.x mypy