【发布时间】:2020-08-11 18:21:18
【问题描述】:
我在表达一对参数的精确类型提示时遇到了麻烦,其中一个参数需要是某个类型的实例的值,另一个需要是类型本身或某个超类型。
您在 Python 中看到这种情况的一种情况是在上下文管理器(类)的 __exit__ 方法中。
import typing as t
from types import TracebackType
from contextlib import AbstractContextManager
class Acme(AbstractContextManager):
def __exit__(self, exc_type: t.Type[Exception], exc: Exception,
tb: Tracebacktype) -> None:
...
这种特定情况可能无关紧要,因为上下文管理器由 Python 内部处理,但我仍然想了解如何表达两个参数,其中第一个是第二个的(超)类型。
从概念上讲,我的问题是我想表达exc 的值的类型为exc_type 或某个子类型。在上面的表达式中,我猜 mypy 会非常满意 LookupError, RuntimeError('foo') 这样的参数,即使 RuntimeError 不是 LookupError 的类型。有没有更好的方法来表达这一点,mypy 会发现这种错误?
更新
在这里使用 TypeVars 尝试测试用例:
import typing as t
C = t.TypeVar('C', bound=t.Collection)
def f(t: t.Type[C], c: C) -> None:
pass
f(t.Dict, [])
我希望 mypy 会抱怨这段代码,因为即使空列表是 Collection 类型,它也不是字典。
【问题讨论】:
-
@modesitt 如果是这样,那就是这样。如果这是一个答案而不是评论,我会接受“不可能这样做”的答案并提供支持证据。
-
我认为这个问题的正确答案会在一两年内改变。让我们在 2021 年重温。
-
是的,我希望如此! Python 的类型正在突飞猛进地改进。也就是说,我几乎宁愿看到 mypy 支持抽象方法的推断类型(如
__exit__),这样我就不用担心精确的注释了。
标签: python generics type-hinting