MutableMapping pop()方法的类型提示定义

2024-04-20 09:41:41 发布

您现在位置:Python中文网/ 问答频道 /正文

为了更好地理解泛型容器类型暗示的工作原理,我研究了^{} file,在MutableMapping类定义中发现了以下几行:

@overload
def pop(self, k: _KT) -> _VT: ...
@overload
def pop(self, k: _KT, default: Union[_VT, _T] = ...) -> Union[_VT, _T]: ...

{do{cd3>的附加参数是这个部分的。只能为MutableMapping指定两个参数:_KT和{}。那么,这个额外的_T参数仍然未指定。类型检查器如何解决第三种类型。。。?在


Tags: self类型参数定义defpop容器file
1条回答
网友
1楼 · 发布于 2024-04-20 09:41:41

我本来打算在评论中留下这个,但是我的回答开始变得有点长了,所以这里是。。。在

Only two parameters can be specified for MutableMapping: _KT and _VT. This extra _T parameter, then, remains unspecified. How does the type checker go about resolving this 3rd type...?

正如@jornsharpe所说,_T是一个类类型参数,而不是一个函数类型参数。基本上,当您调用该方法时,mypy将具有:

  1. 已经将_KT和{}绑定到其他类型。因此,如果我们调用foo: MutableMapping[str, int] = ...,然后调用foo.pop(...),mypy将理解在我们调用str和{}分别绑定到str和{}。在
  2. Mypy还将注意到,如果调用第二个重载,则有一个free(即unbound)类型的参数正在浮动。然后,它将尝试根据我们传入/周围上下文的任何值来推断正确的_T类型是什么。在

    例如,假设我做foo.pop("x", "bar")。这与第二个过载匹配。我们之前也说过,_KT和{}分别绑定到str和{}。然后Mypy注意到_T是未绑定的,并尝试推断一个适当的类型。在

    在这里,我们知道我们传入的值的类型是“str”,参数类型是Union[int, _T](在绑定类型中替换之后)。我们还知道,我们传入的值必须是参数的子类型,我们知道str必须是Union[int, _T]的子类型。在

    然后,Mypy使用上述所有信息/所有已知约束运行一个推理算法,并且能够在本例中推断_T必须是{}类型。

(顺便说一句,mypy的推理算法在这里并不完美。如果表达式特别复杂/当前无法正确处理某些边缘情况,则有时可能无法推断正确的类型。)

如果您想更详细地描述mypy的类型推理算法是如何工作的,可以尝试通过mypy的代码库进行探索。具体来说,mypy调用this function,后者反过来调用code in here。好的警告,这有点难理解。在

In this context is the _T return type covariant...?

我们知道_KT_VT,和{}都是基于{a3}的不变量。在

这三个类型变量中的每一个都可以彼此完全独立。这与运行时行为相匹配:如果我有一个Dict[str, str],那么执行my_dict.pop("x", 4)可能会返回一些字符串或数字4,具体取决于my_dict所包含的内容。在

Does the return type have to be the same type as default or just a compatible subtype?

因此,完全抛开泛型,以下是mypy0.620中的重载规则(简化)。(早期版本的mypy使用了类似的但更灵活的即席算法)。在

  1. 默认情况下,mypy将允许任意两个重载的返回类型是完全任意的:它们之间不需要有任何内在的关系。在
  2. 然而,Mypy将禁止固有不安全过载定义。在以下情况下,两种过载变体被视为本质上不安全的:

    1. 第一个变量的所有参数都与第二个变量兼容。在
    2. 第一个变量的返回类型与第二个变量不兼容(例如不是的子类型)。在

    pop的特定情况下,第一个变量的参数确实与第二个变量兼容:无论出于什么原因,default参数被标记为可选的。这意味着对foo.pop("x")的调用实际上可以匹配这两个重载。在

    然而,第一个重载变量的返回类型是第二个重载变量的子类型:_VT是{}的子类型,不管{}最终是什么。

  3. 当您实际调用重载时,mypy将按照定义的顺序检查可用的重载,并使用匹配的第一个变量。为了确保该算法的行为符合预期,如果重载的定义方式使某些变量无法匹配,mypy将报告一个错误。在

这些规则并不是真的有意义的改变如果我们在混合中加入泛型。在

文档中有关于the nuances of function overloading的更多细节/示例。在

相关问题 更多 >