Python 3.x 如何将mypy推断循环变量固定为;对象";?

Python 3.x 如何将mypy推断循环变量固定为;对象";?,python-3.x,pylint,mypy,Python 3.x,Pylint,Mypy,我做了这个简单的函数,我想用mypy和 派林。它只是解析字符串并将其转换为适当的 类型 重新导入 从键入import Any开始,可调用 def parse_常量(常量:str)->任意: 要注册,请登录[ (重新编译(r'\'(.*)\''),str), (重新编译(r'true',re.IGNORECASE),lambda:true), (重新编译(r'false',re.IGNORECASE),lambda:false), (重新编译(r'([0-9]+)),int), (重新编译(r'(

我做了这个简单的函数,我想用mypy和 派林。它只是解析字符串并将其转换为适当的 类型

重新导入
从键入import Any开始,可调用
def parse_常量(常量:str)->任意:
要注册,请登录[
(重新编译(r'\'(.*)\''),str),
(重新编译(r'true',re.IGNORECASE),lambda:true),
(重新编译(r'false',re.IGNORECASE),lambda:false),
(重新编译(r'([0-9]+)),int),
(重新编译(r'([0-9]+\[0-9]+]),浮点)
]:
匹配=注册完全匹配(常数)
如果匹配项不是无:
如果len(match.groups())==0:
val=无
其他:
val=match.groups()[0]
返回获取值(val)
一无所获
它工作正常,但mypy抱怨:我得到
错误:“object”不可调用
在第18行(
返回get_val(val)

现在如果我把,
str
替换为
lambda x:str(x)
mypy很高兴,但是pylint 可能不需要投诉
Lambda


解决这个问题的正确方法是什么?

问题是MyPy必须从
可调用
类型
的混合中推断出
get_val
。在这种情况下,显式地注释类型以避免过于广泛的推断

for
循环中,只能对循环变量进行注释。通过将iterable移动到循环外部,可以对其进行注释:

重新导入
输入import Any、Callable、Pattern、List、Tuple
案例:列表[Tuple[Pattern[str],可调用]=[
(重新编译(r'\'(.*)\''),str),
(重新编译(r'true',re.IGNORECASE),lambda:true),
(重新编译(r'false',re.IGNORECASE),lambda:false),
(重新编译(r'([0-9]+)),int),
(重新编译(r'([0-9]+\[0-9]+]),浮点)
]
def parse_常量(常量:str)->任意:
对于reg,在以下情况下获取值:
匹配=注册完全匹配(常数)
如果匹配项不是无:
如果len(match.groups())==0:
val=无
其他:
val=match.groups()[0]
返回获取值(val)
一无所获

将案例移到函数之外还有一个额外的优点,即它们只创建一次。这对于
re.compile
尤其重要,它现在只编译一次,然后存储以供重复使用。

原因是MyPy在通过推理混合类型时选择基而不是并集。
type
Callable
的基础是
object
。可能是相关的:非常感谢您给出了清晰的答案(并提供了更清晰的问题标题)!然而我对此有点困惑:mypy抱怨,因为基本上
str
不是一个
Callable
,但如果我明确告诉他这是一个
Callable
,那么他就同意了。我想教训是当我面对这种情况时,要依靠显式输入。再次感谢。@qouify恐怕这并不明显。根本问题是推理有多种选择,例如文本
str
类型为
type[str]
Callable[…,str]
,并且必须选择一种。值得注意的是,一旦推理做出了选择,这将被“锁定”,即使这会导致以后的冲突。通过在推理“锁定”之前的某个点提供注释,您可以影响做出的选择。我明白了。我可能对打字机制不够熟悉,我想我应该在这方面学习更多,以便正确使用mypy。首先,我的假设是类型之间存在某种继承机制,
Type[str]
继承自
Callable
,但这显然是一个错误。谢谢你的帮助。