对于用type()构造的类型,mypy“作为类型无效”

use*_*080 5 python python-3.x mypy

Foo = type('Foo', (), {})
Bar = Optional[Foo]
Run Code Online (Sandbox Code Playgroud)

mypy抱怨 error: Variable "packagename.Foo" is not valid as a type

除了这样做还有其他办法吗

Class Foo:
    pass

Bar = Optional[Foo]
Run Code Online (Sandbox Code Playgroud)

Ale*_*ood 8

作为解决方法,这个怎么样?

from typing import Optional, TYPE_CHECKING

if TYPE_CHECKING:
    class Foo: pass
else:
    Foo = type('Foo', (), {})
    
Bar = Optional[Foo]
Run Code Online (Sandbox Code Playgroud)

typing.TYPE_CHECKING是一个常量,始终位于True编译时,并且始终位于False运行时。通过这种方式,我们可以通过仅告诉 MyPy 静态定义来让其满意,但在运行时我们可以随心所欲地动态化。

但您应该意识到,这在很大程度上是一种解决方法,而不是解决方案。通过这样做,我们本质上是在向类型检查器撒谎关于 的真实定义Foo。这意味着 MyPy 可能无法发现某些地方的错误,并且可能会引发其他地方不存在的错误。在某些情况下,在运行时动态构造类型非常有用,但违背了 Python 中类型检查的一些基本原则,因此如果不进行某种破解,您将很难让类型检查器批准您正在做的事情。

  • 在我的用例中,我有一个返回类的类工厂函数(`var=class_factory()`)。这是我能找到的让 mypy 接受 var 作为类的唯一方法。谢谢! (2认同)