MyPy-"Incompatible types in assignment (expression has type None, variable has type ...)"
MyPy - "Incompatible types in assignment (expression has type None, variable has type ...)"
我有下面的函数,给定一个形式为 'a-02/b-03/foobarbaz_c-04'
的字符串,将提取 a、b[ 之后的数字=30=] 和 c。问题是,对于我的用例,输入字符串可能不包含 c,这样就没有要提取的数字。
代码如下:
from typing import Tuple, Optional
def regex_a_b_c(name: str) -> Tuple[int, int, Optional[int]]:
a_b_info = re.search('a-(\d\d)/b-(\d\d)/', name)
a, b = [int(a_b_info.group(x)) for x in range(1, 3)]
c_info = re.search('c-(\d\d)', name)
if c_info:
c = int(c_info.group(1))
else:
c = None
return a, b, c
我遇到的问题是,尽管试图弄清楚最后一个 return 参数是一个 Optional[int]
,但我无法让我的 linter 停止抱怨变量 c。
我在 c = None
行收到一条警告:
Incompatible types in assignment (expression has type None, variable
has type int)
我该如何解决这个问题?
您应该 return 一个元组 a,b,c
或一个不包括 c 的元组 a,b
。这样,您根本不需要将 None 的值分配给 c。
if c_info:
c = int(c_info.group(1))
return a, b, c
else:
return a, b
如果您不注释变量,mypy 将 infer its type 基于它看到的第一个赋值。
所以在这种情况下,第一个出现c = int(_info.group(1))
行,所以mypy决定类型必须是int
。然后它随后在看到 c = None
.
时抱怨
解决此限制的一种方法是仅向前声明具有预期类型的变量。如果你正在使用 Python 3.6+ 并且可以使用变量注释,你可以这样做:
c: Optional[int]
if c_info:
c = int(c_info.group(1))
else:
c = None
或者更简洁,像这样:
c: Optional[int] = None
if c_info:
c = int(c_info.group(1))
如果您需要支持旧版本的 Python,您可以使用基于注释的语法来注释类型,如下所示:
c = None # type: Optional[int]
if c_info:
c = int(c_info.group(1))
rje 的建议:
if c_info:
c = int(c_info.group(1))
return a, b, c
else:
return a, b, None
...也是合理的
除了 给出的好方法之外,我还发现了另一种方法,可以通过添加如下注释让 mypy 忽略该行:
c = None # type: ignore
这似乎忽略了当前行的类型,但不影响使用该变量的其他区域的类型推断。
我有下面的函数,给定一个形式为 'a-02/b-03/foobarbaz_c-04'
的字符串,将提取 a、b[ 之后的数字=30=] 和 c。问题是,对于我的用例,输入字符串可能不包含 c,这样就没有要提取的数字。
代码如下:
from typing import Tuple, Optional
def regex_a_b_c(name: str) -> Tuple[int, int, Optional[int]]:
a_b_info = re.search('a-(\d\d)/b-(\d\d)/', name)
a, b = [int(a_b_info.group(x)) for x in range(1, 3)]
c_info = re.search('c-(\d\d)', name)
if c_info:
c = int(c_info.group(1))
else:
c = None
return a, b, c
我遇到的问题是,尽管试图弄清楚最后一个 return 参数是一个 Optional[int]
,但我无法让我的 linter 停止抱怨变量 c。
我在 c = None
行收到一条警告:
Incompatible types in assignment (expression has type None, variable has type int)
我该如何解决这个问题?
您应该 return 一个元组 a,b,c
或一个不包括 c 的元组 a,b
。这样,您根本不需要将 None 的值分配给 c。
if c_info:
c = int(c_info.group(1))
return a, b, c
else:
return a, b
如果您不注释变量,mypy 将 infer its type 基于它看到的第一个赋值。
所以在这种情况下,第一个出现c = int(_info.group(1))
行,所以mypy决定类型必须是int
。然后它随后在看到 c = None
.
解决此限制的一种方法是仅向前声明具有预期类型的变量。如果你正在使用 Python 3.6+ 并且可以使用变量注释,你可以这样做:
c: Optional[int]
if c_info:
c = int(c_info.group(1))
else:
c = None
或者更简洁,像这样:
c: Optional[int] = None
if c_info:
c = int(c_info.group(1))
如果您需要支持旧版本的 Python,您可以使用基于注释的语法来注释类型,如下所示:
c = None # type: Optional[int]
if c_info:
c = int(c_info.group(1))
rje 的建议:
if c_info:
c = int(c_info.group(1))
return a, b, c
else:
return a, b, None
...也是合理的
除了
c = None # type: ignore
这似乎忽略了当前行的类型,但不影响使用该变量的其他区域的类型推断。