python - 具有不同 kwargs 的函数的回调协议
问题描述
我有一个将callback
函数作为参数的函数:
def function(arg1: int, callback):
...
我正在尝试为该callback
函数添加类型提示。现在,传递给此函数的回调函数具有相同的位置参数,但 kwargs 可以完全不同(类型和名称)。
def function1(arg1: int, arg2: str, **kwargs1):
...
def function2(arg1: int, arg2: str, **kwargs2):
...
我正在尝试编写一个适合这两个函数的回调协议,但到目前为止,当 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, 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_1
,mypy
会抱怨这一点。这是因为 的公共接口function2
以向后不兼容的方式发生了变化。例如,我必须arg1=0
在任何呼叫站点修改为arg_1=0
.
但是如果我采用相同的功能并重命名kwargs2
为kwargs_2
,那么公共接口实际上并没有改变!这是因为一开始就不可能在调用站点显式引用kwargs
//参数kwargs1
。kwargs2
举个例子:
function2(arg1=0, arg2="", kwargs2={})
如果我要从函数内部转储kwargs2
,它实际上会将键"kwargs2"
映射到{}
,而不是本身是一个空字典。这表明不可能依赖关键字参数的名称。因此,在检查 的公共接口是否与 . 的公共接口匹配mypy
时可以允许不同的名称。function2
Callback
至于类型,kwargs
和kwargs1
都有kwargs2
一个Dict[str, Any]
左注解的类型。由于您在所有 3 方面都保持一致,mypy
因此在此处报告成功,同时还使您能够利用Any
特定于function1
or的关键字参数function2
。
推荐阅读
- google-analytics - GA/360:通过 API 的帐户用户访问时间
- android - 如何在android中保存短信
- continuous-deployment - 基础架构即代码 (IaC) 是针对软件基础架构、虚拟硬件基础架构还是两者兼而有之?
- php - 在 Woocommerce 中使用自定义选择字段触发 update_checkout
- php - 如何使用 Guzzle 进行分页
- html - 如何使用 Nginx 传递没有扩展名的文件?
- c# - 在 VSTS CI/CD 中构建 Hive 项目时出错
- javascript - 从对象创建一个网格数组(THREE.JS 和 GLTF)
- scala - 如何在 Scala 中从 List[Array[String]] 中获取集合
- c# - Swashbuckle MapType
不适用于参数