mypy 抱怨
error: Variable "packagename.Foo" is not valid as a type
Foo = type('Foo', (), {})
Bar = Optional[Foo]
可以通过将类型定义为类来修复此错误:
class Foo:
pass
Bar = Optional[Foo]
还有其他办法解决这个问题吗?我需要保持类型定义动态。
作为解决方法,这个怎么样?
from typing import Optional, TYPE_CHECKING
if TYPE_CHECKING:
class Foo: pass
else:
Foo = type('Foo', (), {})
Bar = Optional[Foo]
typing.TYPE_CHECKING
是一个常量,在编译时始终为 True
,在运行时始终为 False
。通过这种方式,我们可以通过仅告诉 MyPy 静态定义来让 MyPy 满意,但在运行时我们可以随心所欲地动态。
不过,您应该意识到,这在很大程度上是一种解决方法,而不是解决方案。通过这样做,我们本质上是在向类型检查器谎报
Foo
的真实定义。这意味着 MyPy 可能无法发现某些地方的错误,并且可能会引发其他地方不存在的错误。在某些情况下,在运行时动态构造类型非常有用,但违背了 Python 中类型检查的一些基本原则,因此如果不进行某种破解,您将很难让类型检查器批准您正在做的事情。
这是相关的 mypy issue 8897。就我而言,给出这个例子:
Bla = type("Bla", (), {}) # type: ignore[valid-type, misc]
class Foo(Bla):
pass
我可以通过明确输入作业的 LHS 来说服 mypy 接受
Bla
:
Bla: type = type("Bla", (), {})
仅使用
mypy 1.3.0 (compiled: yes)
进行测试。