带有 numpy ndarray 和 pandas 数据框的 mypy 重载函数(签名参数类型相同或更广泛)
mypy overload function with numpy ndarray and pandas dataframe (signature parameter type(s) are the same or broader)
我有一个函数可以对 numpy 数组或 pandas 数据帧执行一些算术运算(分位数归一化)。当你放入一个 ndarray 时,你应该得到一个 ndarray,当你放入一个 pandas 数据帧时,你应该得到一个数据帧:
from typing import Union, overload
@overload
def quantile_normalize(data: pd.DataFrame) -> pd.DataFrame: ...
@overload
def quantile_normalize(data: np.ndarray) -> np.ndarray: ...
def quantile_normalize(data: Union[pd.DataFrame, np.ndarray]) -> Union[pd.DataFrame, np.ndarray]:
pass
然而,当我尝试用 mypy 测试它时,它会抱怨:
qnorm/quantile_normalize.py:72: error: Overloaded function signature 2 will never be matched: signature 1's parameter type(s) are the same or broader
到目前为止我发现的与此问题相关的问题和答案似乎都与可选的 input/output 和 None 类型有关。 pandas dataframe 和 numpy array 是相关的,但是,它们应该可以被 mypy 区分。
当库缺少类型提示时,每次导入都将解析为 Any
。 numpy
和 pandas
都不符合 PEP 526(不提供任何类型提示)并且在 typeshed
中没有存根,因此 pd.DataFrame
和 np.ndarray
都将解析为 Any
,因此两个重载都解析为 def quantile_normalize(data: Any) -> Any: ...
。要解决此问题,请为 numpy
和 pandas
添加存根。
要么使用现有的类型存根 - 我使用 data-science-types
(PyPI, GitHub) 为 numpy
、pandas
和 matplotlib
:[=32 提供存根=]
$ pip install data-science-types
现在 pd.DataFrame
和 np.ndarray
将在 运行 宁 mypy
时正确解析。这还将免费为您提供支持 PEP 526(例如 Visual Studio Code 或 WingIDE)的每个 IDE 中更好的代码补全。
或者,如果您t/don不想添加存根包,请编写您自己的最小存根,例如
# _typeshed/pandas/__init__.pyi
from typing import Any
def __getattr__(name: str) -> Any: ... # incomplete
class DataFrame:
def __getattr__(self, name: str) -> Any: ... # incomplete
和
# _typeshed/numpy/__init__.pyi
from typing import Any
def __getattr__(name: str) -> Any: ... # incomplete
class ndarray:
def __getattr__(self, name: str) -> Any: ... # incomplete
和运行 MYPYPATH=_typeshed mypy ...
.
我有一个函数可以对 numpy 数组或 pandas 数据帧执行一些算术运算(分位数归一化)。当你放入一个 ndarray 时,你应该得到一个 ndarray,当你放入一个 pandas 数据帧时,你应该得到一个数据帧:
from typing import Union, overload
@overload
def quantile_normalize(data: pd.DataFrame) -> pd.DataFrame: ...
@overload
def quantile_normalize(data: np.ndarray) -> np.ndarray: ...
def quantile_normalize(data: Union[pd.DataFrame, np.ndarray]) -> Union[pd.DataFrame, np.ndarray]:
pass
然而,当我尝试用 mypy 测试它时,它会抱怨:
qnorm/quantile_normalize.py:72: error: Overloaded function signature 2 will never be matched: signature 1's parameter type(s) are the same or broader
到目前为止我发现的与此问题相关的问题和答案似乎都与可选的 input/output 和 None 类型有关。 pandas dataframe 和 numpy array 是相关的,但是,它们应该可以被 mypy 区分。
当库缺少类型提示时,每次导入都将解析为 Any
。 numpy
和 pandas
都不符合 PEP 526(不提供任何类型提示)并且在 typeshed
中没有存根,因此 pd.DataFrame
和 np.ndarray
都将解析为 Any
,因此两个重载都解析为 def quantile_normalize(data: Any) -> Any: ...
。要解决此问题,请为 numpy
和 pandas
添加存根。
要么使用现有的类型存根 - 我使用 data-science-types
(PyPI, GitHub) 为 numpy
、pandas
和 matplotlib
:[=32 提供存根=]
$ pip install data-science-types
现在 pd.DataFrame
和 np.ndarray
将在 运行 宁 mypy
时正确解析。这还将免费为您提供支持 PEP 526(例如 Visual Studio Code 或 WingIDE)的每个 IDE 中更好的代码补全。
或者,如果您t/don不想添加存根包,请编写您自己的最小存根,例如
# _typeshed/pandas/__init__.pyi
from typing import Any
def __getattr__(name: str) -> Any: ... # incomplete
class DataFrame:
def __getattr__(self, name: str) -> Any: ... # incomplete
和
# _typeshed/numpy/__init__.pyi
from typing import Any
def __getattr__(name: str) -> Any: ... # incomplete
class ndarray:
def __getattr__(self, name: str) -> Any: ... # incomplete
和运行 MYPYPATH=_typeshed mypy ...
.