如何解决如何将 mypy 推断循环变量修复为“对象”?
我做了这个简单的函数,我想用 mypy 和 派林特。它只是解析一个字符串并将其转换为适当的 类型。
<?php
echo "Hello world";
?>
它工作正常,但 mypy 抱怨:我得到 import re
from typing import Any,Callable
def parse_constant(constant: str) -> Any:
for reg,get_val in [
(re.compile(r'\'(.*)\''),str),(re.compile(r'true',re.IGNORECASE),lambda _: True),(re.compile(r'false',lambda _: False),(re.compile(r'([0-9]+)'),int),(re.compile(r'([0-9]+\.[0-9]+)'),float)
]:
match = reg.fullmatch(constant)
if match is not None:
if len(match.groups()) == 0:
val = None
else:
val = match.groups()[0]
return get_val(val)
return None
在第 18 行 (error: "object" not callable
)。
现在如果我用 return get_val(val)
替换 str
mypy 很高兴但是 pylint
向 lambda x: str(x)
投诉。
解决这个问题的正确方法是什么?
解决方法
问题是 MyPy 必须从 get_val
和 Callable
的混合中推断出 Type
。在这种情况下,MyPy selects the base instead of the union of the types. 显式注释类型以避免推断过于宽泛。
在 for
循环内部,只能注释循环变量。通过将迭代器移出循环,可以对其进行注释:
import re
from typing import Any,Callable,Pattern,List,Tuple
cases: List[Tuple[Pattern[str],Callable]] = [
(re.compile(r'\'(.*)\''),str),(re.compile(r'true',re.IGNORECASE),lambda _: True),(re.compile(r'false',lambda _: False),(re.compile(r'([0-9]+)'),int),(re.compile(r'([0-9]+\.[0-9]+)'),float)
]
def parse_constant(constant: str) -> Any:
for reg,get_val in cases:
match = reg.fullmatch(constant)
if match is not None:
if len(match.groups()) == 0:
val = None
else:
val = match.groups()[0]
return get_val(val)
return None
将案例移到函数之外还有一个额外的好处,即它们只创建一次。这对于 re.compile
尤其重要,它现在编译一次,然后存储以备重复使用。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。