python-3.x - 如何根据运行时条件指定类型

标签 python-3.x mypy

我正在使用 mypy 和协议(protocol),如果可能的话,我遇到了一个我想要类型提示的地方,但我无法弄清楚我应该如何设置它,所以 mypy 不会出错。

考虑以下示例:

class TProtocol(Protocol):
    t: str

@attrs(auto_attribs=True)
class T:
    t: str
    t2: str

@attrs(auto_attribs=True)
class T2:
    t: str

def func(var: TProtocol) -> None:
    if some_condition:
        var: T
        reveal_type(var)
    else:
        reveal_type(var)

虽然非常做作,但它说明了我的目标,即我有一些运行时条件,如果满足,我会根据代码库的知识知道该变量的类型。然后我想将这些知识传递给 mypy,以便进一步的类型检查使用该类型。

相同的示例可以替换为联合。一些运行时检查会根据代码库的知识明确告诉我我拥有哪种类型。然后,我想根据外部知识明确告诉 mypy 哪种类型用于进一步类型检查。

上面的示例引发了一个错误,指出 var 已定义。我试过 allow_redefinition选项,它没有改变输出。

最佳答案

使用 typing.cast 强制将变量声明为特定类型。这忽略了任何其他类型的信息,并且也适用于运行时分支。

def func(var: TProtocol) -> None:
    reveal_type(var)         # line 21
    if some_condition:
        var = cast(T, var)   # line 23
        reveal_type(var)
    else:
        var = cast(T2, var)  # line 26
        reveal_type(var)

这使得 mypy处理 var 的每个强制转换事件不同,即在每个分支之前和内部:
type_tests.py:21: note: Revealed type is 'type_tests.TProtocol'
type_tests.py:24: note: Revealed type is 'type_tests.T'
type_tests.py:27: note: Revealed type is 'type_tests.T2'

关于python-3.x - 如何根据运行时条件指定类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59165875/

相关文章:

python - 您可以在 Python 类型注释中指定方差吗?

python - 'dict' 对象没有属性 'id'

mysql - Mac osx 上的 Apache 超集

python - 绘制烛台(matplotlib)

python - 用 pandas 转换格式不良的字典

python - 即使测试了所有案例,MyPy 也会给出错误 "Missing return statement"

python - 获取具有不同子列表数据类型的列表元素的交集

python - 为什么 mypy 会忽略包含与 TypeVar 不兼容的类型的泛型变量?

python - 获取与静态类型检查器一起使用的 TypedDict 值类型的函数

python - mypy 设置字典键/接口(interface)