试图避免打字问题,我经常遇到同样的问题。
例如我有一个函数
x
很少返回值 None
,其他时候它都会返回 int
。
def x(i: int) -> Union[int, None]:
if i == 0:
return
return i
def test(i: int):
a = x(i)
# typing issue: *= not supported for types int | None and int
a *= 25
x
在代码库中经常使用,大多数时候i
已经被检查了一百次,x(i)
确实会返回int
而不是None
。
立即将其用作 int
会产生打字警告 - 例如您无法将可能的 None
值相乘。
这种情况的最佳实践是什么?
我考虑过的想法:
None
检查 if a is None: return
没有任何意义,因为它已经是 已知。a *= 25 # type: ignore
将使 a
成为 Unknown
类型。a = x(i) # type: int
将使警告消失。但会产生一个新的警告“int | None不能分配给int”我通常最终会将
x
的返回类型更改为 int
,在 ignore
中添加 return # type: ignore
并在文档字符串中提到它可以返回 None
,这有助于避免类型警告污染整个代码库。这是最好的方法吗?
def x(i: int) -> int:
"""might also return `None`"""
if i == 0:
return # type: ignore
return i
在这种情况下,异常可能比您从未期望达到的返回语句更好。
def x(i: int) -> int:
if i == 0:
raise ValueError("didn't expect i==0")
return i
def test(i: int):
try:
a = x(i)
except ValueError:
pass
a *= 25
确信已充分验证
x
的论点的代码可以省略 try
语句。