如何输入提示具有默认参数的函数的 Callable?

Don*_*rry 36 python python-3.x mypy python-typing

我正在尝试输入 Hint the function bar,但是Too few arguments当我运行 mypy.txt 时出现错误。

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))
Run Code Online (Sandbox Code Playgroud)

我也尝试过:

  • Callable[[], float](出现Too many arguments错误)
  • Callable[[Optional[int]], float](又出现一个错误)

那么,我应该如何进行函数的类型提示呢bar

Mar*_*hac 44

定义这个:

class Foo(Protocol):
    def __call__(self, x: int = ..., /) -> float:
        ...
Run Code Online (Sandbox Code Playgroud)

然后输入提示fooasFoo而不是Callable[[int], float]回调协议允许您:

定义灵活的回调类型,这些类型很难(甚至不可能)使用Callable[...]语法来表达

和可选参数是那些不可能用普通Callable. 签名末尾的 会生成一个/仅位置参数,它允许任何传递的函数具有不是的参数名称(您的特定示例会调用它)。如果您删除了,那么不仅类型必须按预期排列,而且名称也必须排列,因为您将暗示可以使用关键字参数调用它。因为不使用关键字参数进行调用,所以通过忽略 来选择该行为会给用户带来不灵活性(并且会使您当前的示例仍然失败,因为)。__call__xbarxfooarg/Foobarfoo/bar"arg" != "x"

  • @DonLarry 类型为“Optional”(“Callable[[Optional[int]], bool”)的参数可以表达,但您需要传递“None”。不支持不需要传递任何内容的可选参数(因此带有默认值的参数),因为它需要能够为“Callable”的通用参数指定“=”(例如“Callable[[int = 123”) ], bool]`,这是不受支持的语法。 (6认同)
  • 从技术上讲,它不一定是“=”,可以是其他语法,但在“协议”之外尚未达成一致(https://github.com/python/typing/issues/264)。 (2认同)
  • @DonLarry 是的,这就是我做出区分的原因。 (2认同)