Sel*_*lva 0 python mypy python-typing
我有一个如下所示的功能,
def run_the_f(f):
# run f function after some validation
Run Code Online (Sandbox Code Playgroud)
根据某些条件,f 函数的签名会发生如下变化f(1.0), f(1.0,2.0), f(1.0,2.0,3.0,..)。换句话说,f 中输入参数的数量可以变化,类似于pyspark 中的 udf f。
我正在使用 mypy 并且我在下面尝试了失败,
def run_the_f(f: Callable[[*float],float]):
# run f after some validation
Run Code Online (Sandbox Code Playgroud)
有人可以支持在 Callable 中填写什么吗?
使用typing.Protocol:
from typing import Protocol, TypeVar
from abc import abstractmethod
T_contra = TypeVar('T_contra', contravariant=True)
T_co = TypeVar('T_co', covariant=True)
class SupportsCallWithArgs(Protocol[T_contra, T_co]):
@abstractmethod
def __call__(self, *args: T_contra) -> T_co:
pass
def run_the_f(f: SupportsCallWithArgs[float, float]):
f(1., 2., 3.) # pass
f([]) # fail: Argument to "__call__" of "SupportsCallWithArgs" has incompatible type "List[<nothing>]";
# expected "float"
def f(*args: float) -> float:
pass
run_the_f(f) # pass
run_the_f(lambda: None) # fail: Argument 1 to "run_the_f" has incompatible type "Callable[[], None]";
# expected "SupportsCallWithArgs[float, float]"
Run Code Online (Sandbox Code Playgroud)
VarArg在mypy的扩展包中也许是一个更简单的选择(根据评论区提供的参考,不推荐这种选择):
from collections.abc import Callable
from mypy_extensions import VarArg
def run_the_f(f: Callable[[VarArg(float)], float]):
f(1., 2., 3.) # pass
Run Code Online (Sandbox Code Playgroud)
但这似乎只是mypy的自我催眠,Pycharm的类型检查器会提示2.and3.作为意外的参数f:
# mypy_extensions.py
def VarArg(type=Any):
"""A *args-style variadic positional argument"""
return type
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
793 次 |
| 最近记录: |