我大量使用python 3提供的python类型支持.

最近,我试图将一个函数作为参数传递,但我找不到使用kwargsintyping.Callable签名的任何帮助.

请判断下面的代码和注释.

import typing

# some function with singnature typing
def fn1_as_arg_with_kwargs(a: int, b: float) -> float:
    return a + b

# some function with singnature typing
def fn2_as_arg_with_kwargs(a: int, b: float) -> float:
    return a * b

# function that get callables as arg
# this works with typing
def function_executor(
        a: int, 
        b: float, 
        fn: typing.Callable[[int, float], float]):
    return fn(a, b)

# But what if I want to name my kwargs 
# (something like below which does not work)
# ... this will help me more complex scenarios 
# ... or am I expecting a lot from python3 ;)
def function_executor(
        a: int, 
        b: float, 
        fn: typing.Callable[["a": int, "b": float], float]):
    return fn(a=a, b=b)

推荐答案

你可能在找Callback protocols个.

简而言之,当你想用一个复杂的签名来表达一个可调用的函数时,你需要做的是创建一个自定义协议,定义一个__call__方法,并使用你想要的精确签名.

例如,在您的情况下:

from typing import Protocol

# Or, if you want to support Python 3.7 and below, install the typing_extensions
# module via pip and do the below:
from typing_extensions import Protocol

class MyCallable(Protocol):
    def __call__(self, a: int, b: float) -> float: ...

def good(a: int, b: float) -> float: ...

def bad(x: int, y: float) -> float: ...


def function_executor(a: int, b: float, fn: MyCallable) -> float:
    return fn(a=a, b=b)

function_executor(1, 2.3, good)  # Ok!
function_executor(1, 2.3, bad)   # Errors

如果您try 使用mypy对该程序进行类型判断,最后一行将出现以下错误(当然是神秘的):

Argument 3 to "function_executor" has incompatible type "Callable[[int, float], float]"; expected "MyCallable"

(回调协议有些新,因此希望错误消息的质量会随着时间的推移而提高.)

Python-3.x相关问答推荐

使用Python装载. iso文件

安装grpcio时出现错误DeproationWarning:pkg_resource

从.csv导入将文件夹路径加入到文件名

文件名中的文件打开和撇号

Pandas 插入的速度太慢了.对于跟踪代码,什么是更快的替代方案?

我们可以在每个可以使用 Pandas Join 的用例中使用 Pandas merge 吗?

错误:无法为 pyconcorde 构建轮子,这是安装基于 pyproject.toml 的项目所必需的

在 string.find() 条件下加入两个 Dataframes

如果集合大于 len(x),则 pandas 在重复的行中拆分集合列

使用 multiprocessing 处理图像

Pandas 窗口聚合两个排序表

attrs 将 list[str] 转换为 list[float]

使用正则表达式捕获组解析地址

如何并行化文件下载?

判断对 python 3 支持的要求

Python 错误:IndexError:字符串索引超出范围

在 Pandas 数据框中显示对图

Python 3 与 Python 2 映射行为

在 Python 3 中获取所有超类

带百分号的 Python 字符串格式