我有一个带有 和
inplace
参数的函数。按照良好的实践,如果函数修改了输入 (None
),则返回 inplace=True
,并返回修改后的输入副本,否则 (inplace=False
)。 (我现在的偏好是不要有 inplace
争论,但那艘船航行了。)
我这样输入函数:
from typing import Union
A = TypeVar("A")
def func(data: A, inplace=False) -> Union[A, None]:
if inplace:
return None
...
return data.copy()
但是以下有一个打字错误:
modified_data = func([1, 2,3])
modified_data.append(4)
说 None 类型对象没有追加属性。这是正确的:根据提示的编写方式,类型检查器应该说这是错误的,因为我们不知道
modified_data
的类型(给定类型提示)。
但这很令人讨厌,我们希望类型检查器处理这种情况,并在 inplace==True 时引发打字,否则不引发打字。有办法处理吗?
您可以使用
@overload
(详情这里)。但对于你的例子来说,它看起来像这样:
from typing import List, Literal, Union, TypeVar, overload
A = TypeVar("A")
@overload
def func(data: List[A], inplace: Literal[True]) -> None: ...
@overload
def func(data: List[A], inplace: Literal[False] = ...) -> List[A]: ...
def func(data: List[A], inplace: bool=False) -> Union[List[A], None]:
if inplace:
return None
return data.copy()
modified_data = func([1, 2,3])
modified_data.append(4)
func(modified_data, inplace=True)
我们为 mypy 类型检查器将使用的函数定义重载。第一种情况是,如果
inplace=True
(因此 Literal[True]
)则没有输出 None
。
@overload
def func(data: List[A], inplace: Literal[True]) -> None: ...
当
inplace=False
时,我们得到List[A]
的输出(我用A
替换List[A]
,因为任意A
不实现.copy()
)。请注意 ...
中的 inplace: Literal[False] = ...
,因为这是此函数的默认情况。
@overload
def func(data: List[A], inplace: Literal[False] = ...) -> List[A]: ...
然后可以使用Mypy查看是否有错误。就我而言,我提供的整个示例不会返回任何错误。