繁体   English   中英

具有不同 kwargs 的函数的回调协议

[英]Callback protocol for functions with different kwargs

我有一个将callback函数作为参数的函数:

def function(arg1: int, callback):
    ...

我正在尝试为callback函数添加类型提示。 现在,传递给该函数的回调函数具有相同的位置参数,但 kwargs 可以完全不同(类型和名称)。

def function1(arg1: int, arg2: str, **kwargs1):
    ...

def function2(arg1: int, arg2: str, **kwargs2):
    ...

我正在尝试编写一个适合这 2 个函数的回调协议,但到目前为止,当 kwargs 不同时,我没有看到一种方法可以使此工作正常进行。 在这种情况下,有没有办法创建统一的回调协议?

您可以创建此回调协议:

from typing_extensions import Protocol


class Callback(Protocol):
    def __call__(self, arg1: int, arg2: str, **kwargs): ...

并键入提示callback作为Callback

def function(arg1: int, callback: Callback): ...

现在,在这三个函数调用中:

def function1(arg1: int, arg2: str, **kwargs1): ...
def function2(arg1: int, arg2: str, **kwargs2): ...
def function3(arg1: int): ...

function(0, function1) # Success.
function(0, function2) # Success.
function(0, function3) # Error.

mypy将报告前两个成功,但由于缺少arg2报告第三个错误。

这里要意识到的关键是关键字参数参数的名称实际上并不重要。 如果我使用function2并将arg1重命名为arg_1mypy会抱怨。 这是因为function2的公共接口以向后不兼容的方式发生了变化。 例如,我必须在任何调用站点将arg1=0修改为arg_1=0

但是如果我使用相同的函数并将kwargs2重命名为kwargs_2 ,公共接口实际上并没有改变! 这是因为首先不可能在调用站点明确引用kwargs / kwargs1 / kwargs2参数。 拿这个例子:

function2(arg1=0, arg2="", kwargs2={})

如果我要从函数内部转储kwargs2 ,它实际上会将键"kwargs2"映射到{} ,而不是本身是一个空字典。 这表明不可能依赖于关键字参数的名称。 因此,在检查function2的公共接口是否与Callback的公共接口匹配时, mypy可以允许不同的名称。

至于类型, kwargskwargs1kwargs2都有一个类型的Dict[str, Any]左注释。 由于您在所有 3 个方面都是一致的,因此mypy在这里报告成功,同时还使您能够利用Any作为特定于function1function2关键字参数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM