假设我有一个函数接受一个值和任意数量的函数,让我们为 chain_call 调用该函数。
如果没有类型,一个简单的天真的实现将是:
def chain_call(input_value, *args):
for function in args:
input_value = function(input_value)
return input_value
正如您想象的那样,input_value 实际上可以是任何东西,但它始终与 *args: List[Callable]
中第一个 Callable
的第一个也是唯一必需的参数相同.
从这里开始,Callable
的第一个也是唯一一个必需的参数与前面的项目返回类型相同。
到目前为止,我已经设法定义了一个非常通用的类型,但它太松散了。
def chain_call(input_value: Any, *args: List[Callable[Any], Any]) -> Any: ...
我真正喜欢的是这样的
T = TypeVar('T')
def chain_call(input_value: T, *args: List[Callable[T, ...], tr]) -> tr: ...
其中 Callable n+1
的 T
是 Callable n
的 tr
并且最终的返回类型是Callable n_max
的 tr。我不确定如何用类型系统表达这一点,希望得到任何指导。
最佳答案
这个完全类型化的函数存在于 dry-python/returns
中。
我们称之为流
:
from returns.pipeline import flow
assert flow('1', int, float, str) == '1.0'
flow
是通过我们的库附带的自定义 mypy
插件完全输入的。所以,它会捕获这个错误案例(和 many others ):
from returns.pipeline import flow
def convert(arg: str) -> float:
...
flow('1', int, convert)
# error: Argument 1 to "convert" has incompatible type "int"; expected "str"
文档:https://returns.readthedocs.io/en/latest/pages/pipeline.html
关于python - python 类型注释中的链式引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50570524/