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

问题描述

我有一个将.load { display: flex; justify-content: center; } 函数作为参数的函数:

callback

我正在尝试为def function(arg1: int,callback): ... 函数添加类型提示。现在,传递给该函数的回调函数具有相同的位置args,但kwarg可以完全不同(类型和名称都相同)。

callback

我正在尝试编写适合这两个功能的Callback Protocol,但是到目前为止,当kwarg不同时,我还没有找到一种使之起作用的方法。在这种情况下,有没有办法创建统一的回调协议?

解决方法

您可以创建此回调协议:

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,**kwargs1): ...
def function2(arg1: int,**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"映射到{},而不是一个空的字典本身。这表明不可能依靠keyword-arguments参数的名称。因此,mypy可以在检查function2的公共接口是否与Callback的公共接口匹配时允许使用不同的名称。

对于类型,kwargskwargs1kwargs2都带有Dict[str,Any]类型的注释。由于您在这3个方面都保持一致,因此mypy在此报告成功,同时还使您可以利用Any来获取function1function2特定的关键字参数。>

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...