【问题标题】:Mypy seems to ignore bound of a TypeVar typeMypy 似乎忽略了 TypeVar 类型的界限
【发布时间】:2019-01-29 03:47:05
【问题描述】:

例如,我有一段代码如下:

from typing import Type, TypeVar, cast

class SuperClass:
    pass


T = TypeVar('T', bound=SuperClass)


def cast_to(obj: SuperClass, cast_to: Type[T] = SuperClass) -> T:
    return cast(cast_to, obj)

我把它保存在type_check.py。如果我在上面运行 mypy,我会收到以下错误消息:

type_check.py:10: error: Incompatible default for argument "cast_to" (default has type "Type[SuperClass]", argument has type "Type[T]")
type_check.py:11: error: Invalid type "cast_to"

根据我对TypeVar中的bound的理解,只要一个TSuperClass的子类,应该没问题。但是为什么 mypy 在这里抛出错误呢?谢谢!

【问题讨论】:

    标签: python mypy python-typing


    【解决方案1】:

    你的代码有两个问题:首先你的cast_to函数的签名应该是:

    def cast_to(obj: SuperClass, cast_to: Type[T] = Type[SuperClass]) -> T:
    

    然后,在您的cast 语句中,我不确定mypy 是否允许您使用cast_to 作为cast 的第一个参数。相反,您可以尝试:

    def cast_to(obj: SuperClass, cast_to: Type[T]) -> T:
        return cast(T, obj)
    

    当然,使用此定义,您将无法仅使用一个参数调用 cast_to


    我现在要问:你为什么觉得你需要这样做?你确定你的设计是好的吗? cast 应该在非常特殊的情况下使用;文档指出:

    强制类型转换用于消除虚假的类型检查器警告,并在类型检查器无法完全理解发生了什么时为它提供一点帮助。

    所以你应该在这里认真质疑你的设计!给我们更多关于你想要达到的目标的信息。也许有比你想做的更好、更干净的设计。

    【讨论】:

    • 感谢您的回复!基本上,我正在尝试构建一个可以自动将加载的对象转换为指定类型的反序列化函数,并且我想将类型限制为SuperClass的子类型。
    • @NoSegfault 对,这就是我从你的代码中理解的。但是为什么你需要这样做呢?你的对象来自哪里? mypy 不能跟踪它们的类型吗? (如果不是,为什么?在你的设计中是什么让 mypy 无法跟踪对象的类型?)。
    • 对象来自加载的pickle,它可以是SuperClass的任何子类。实际上,在我的代码中,cast_to 函数不是获取对象,而是获取pickle 文件的路径,并且该函数被命名为loadload 的返回类型是 SuperClass,尽管它实际上是 SuperClass 的子类。当我使用对象时,这是有问题的,因为类型检查器会抱怨SuperClass 中未定义某些方法。最初,每次加载对象时我都会进行类型转换,这很烦人。所以我只是将 cast 融合到 load 函数中。
    • @NoSegfault 好的,那是有道理的!
    • 感谢您的帮助!
    猜你喜欢
    • 2014-01-12
    • 2018-04-01
    • 2021-10-28
    • 2016-09-30
    • 2016-03-16
    • 2014-02-03
    • 2012-03-11
    • 2013-09-07
    • 2016-08-12
    相关资源
    最近更新 更多