我一直在努力编写“可变”参数列表类型定义。
例如,将类型赋予:
def foo(fn, *args):
return fn(*args)
我能做的最好的就是使用这里的建议:
from typing import overload, Callable, TypeVar
A = TypeVar('A')
B = TypeVar('B')
C = TypeVar('C')
R = TypeVar('R')
@overload
def foo(fn: Callable[[A], R], a: A) -> R: ...
@overload
def foo(fn: Callable[[A, B], R], a: A, b: B) -> R: ...
@overload
def foo(fn: Callable[[A, B, C], R], a: A, b: B, c: C) -> R: ...
def foo(fn, *args):
return fn(*args)
这主要是做正确的事情......例如,给定:
def bar(i: int, j: int) -> None:
print(i)
以下成功:
foo(bar, 10, 12)
虽然这些失败:
foo(bar, 10)
foo(bar, 10, 'a')
foo(bar, 10, 12) + 1
但如果我检查mypy --strict
我会得到:
test.py:15: error: Function is missing a type annotation
(也就是说最终foo
定义本身没有任何类型)
我可以重新定义foo
为:
def foo(fn: Callable[..., R], *args: Any) -> R:
return fn(*args)
但是当我跑步时,mypy --strict
我得到:
test.py:15: error: Overloaded function implementation does not accept all possible arguments of signature 1
test.py:15: error: Overloaded function implementation does not accept all possible arguments of signature 2
test.py:15: error: Overloaded function implementation does not accept all possible arguments of signature 3
我真的不明白。
如果有人可以提出一种更好的方法来为这种函数提供类型,那将不胜感激!如果我也可以在不列出很多overload
很好的情况下做到这一点,那么真正的定义也有一些“仅限关键字”的论点,不必每次都重复