向以下函数添加类型提示的正确方法是什么?
from typing import Callable
def format_callback(f: Callable) -> Callable:
"""Function to wrap a function to use as a click callback.
Taken from https://stackoverflow.com/a/42110044/8056572
"""
return lambda _, __, x: f(x)
现在
mypy
正在向Missing type parameters for generic type "Callable"
抱怨
代码需要兼容Python 3.9和3.10。如果需要的话我可以使用
typing_extensions
。
编辑:
以下通过了
mypy
,但有太多Any
不适合我的口味。有更好的办法吗?
from typing import Any
from typing import Callable
import click
def format_callback(f: Callable[[Any], Any]) -> Callable[[click.Context, dict[str, Any], Any], Any]:
"""Function to wrap a function to use as a click callback.
Taken from https://stackoverflow.com/a/42110044/8056572
"""
return lambda _, __, x: f(x)
无需查看
click
,您可以做的直接修复是提供与 f(x)
匹配的类型变量:
from typing import Any, Callable, TypeVar
import click
ArgT = TypeVar("ArgT")
ReturnT = TypeVar("ReturnT")
def format_callback(
f: Callable[[ArgT], ReturnT]
) -> Callable[[click.Context, dict[str, Any], ArgT], ReturnT]:
return lambda _, __, x: f(x)
这将防止您在
format_callback
的内部输入错误的内容。
简单扫描一下
click
似乎表明您希望将 format_callback
的返回值传递给以下类构造函数之一或其子类构造函数:
click.core.Parameter.__init__::callback
:
callback: t.Optional[t.Callable[[Context, "Parameter", t.Any], t.Any]]
click.core.Command.__init__::callback
callback: t.Optional[t.Callable[..., t.Any]]
现在,根据您链接到的其他答案,它将关键字参数
callback
传递给@click.argument
和@click.option
,看起来您实际上想使用click.core.Parameter.__init__
,因为装饰器的后备类分别是 ArgumentClass = click.core.Argument
和 OptionClass = click.core.Option
,它们是 click.Core.Parameter
的 both 子类。这意味着根据
Callable
的类型注释,返回 dict[str, Any]
类型的第二个参数不能是 click.core.Parameter.__init__::callback
。那么,你真的应该用这个来代替:
def format_callback(
f: Callable[[ArgT], ReturnT]
) -> Callable[[click.Context, click.Parameter, ArgT], ReturnT]:
return lambda _, __, x: f(x)
由于您将
click.Context
和 click.Parameter
丢弃为 _, __
中的 lambda
,当然,前提是这些仅用于文档目的。他们很容易成为object, object
。