如何键入带有默认参数的函数的可调用提示?

How to type hint a Callable of a function with default arguments?

我正在尝试键入提示函数 bar,但是当我 运行 mypy.

时出现 Too few arguments 错误
from typing import Callable, Optional

def foo(arg: int = 123) -> float:
    return arg+0.1

def bar(foo: Callable[[int], float], arg: Optional[int] = None) -> float:
    if arg:
        return foo(arg)
    return foo()

print(bar(foo))
print(bar(foo, 90))

我也试过:

那么,bar函数的Type Hinting应该怎么做呢?

定义这个:

class Foo(Protocol):
    def __call__(self, x: int = ..., /) -> float:
        ...

然后键入提示 foo 作为 Foo 而不是 Callable[[int], float]Callback protocols 允许您:

define flexible callback types that are hard (or even impossible) to express using the Callable[...] syntax

和可选参数是不可能用普通 Callable 表达的东西之一。 __call__ 签名末尾的 / 使 x 成为 positional-only parameter,这允许任何传递给 bar 的函数具有一个不属于x(您的 foo 的具体示例将其称为 arg)。如果您删除了 /,那么不仅类型必须按预期排列,而且名称也必须排列,因为您暗示可以使用关键字参数调用 Foo。因为 bar 不使用关键字参数调用 foo,所以通过省略 / 选择该行为会对 bar 的用户施加不灵活性(并且会使您当前的示例仍然失败,因为 "arg" != "x").