python - 引号中的 mypy 显式类型提示仍然给出未定义的错误

标签 python type-hinting mypy

我正在尝试做以下事情:

self.sender = None # type: 'Node'

我无法导入 Node,因为我会得到一个循环。所以我把它写在引号中,就像这里提到的那样 http://mypy.readthedocs.io/en/latest/common_issues.html#import-cycles 但我仍然收到以下错误

error: Name 'Node' is not defined

有什么解决办法吗?

谢谢!

最佳答案

简短的回答,您需要包含该类的模块名称,并且需要在一些无法访问的代码中导入该模块,如下所示:

if False:
    # for forward-reference type-checking:
    import mymodule

class MyClass(object):
    def __init__(self):
        self.sender = None  # type: mymodule.Node

为了理解为什么需要这样做(以及为什么它有效),您必须首先意识到 mypy 正在执行静态代码分析。这意味着它不会导入您的模块,而是解析和分析从模块文件中读取的文本。

当导入上面的模块时,import mymodule行将永远不会运行,因此将避免循环导入,但它仍然可供mypy解析。这就是 mypy 在分析过程中解析对 mymodule.Node 的引用的方式。

为了完整起见,我应该提到,并不要求您使用模块名称,您可以使用任何在解析过程中不会引起冲突的名称:

if False:
    from mymodule import Node

class MyClass(object):
    def __init__(self):
        self.sender = None  # type: Node

另请注意,您不需要在注释中出现的类型名称周围使用引号。仅当类型注释直接出现在 python 对象中时才需要这样做。以下是可能发生这种情况的一些场景:

from typing import Optional, NamedTuple
if False:
    from mymodule import Node

NodeInfo = NamedTuple('NodeInfo', [('node', 'Node'), ('info', dict)])

class MyClass(object):
    def __init__(self, sender: Optional['Node'] = None):
        self.sender = sender

关于python - 引号中的 mypy 显式类型提示仍然给出未定义的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37734209/

相关文章:

python - 如何在保留类型的同时重写类 __init__ 方法

python - 如何保持导入轻量级并且仍然正确键入注释?

python - 如何在 bash/Python/Fabric/sh 脚本中使用 pew?

python - Psycopg2 操作错误 : could not connect to server : No such file or directory

python - 包装 pyspark Pipeline.__init__ 和装饰器

python - sklearn 成对距离结果意外地不对称

python - “类型”对象在函数定义时不可订阅

Python 输入 : return type with generics like Clazz[T] as in Java Clazz<T>

python - 如何在 for 循环中注释类型?

python-3.x - Mypy 迭代器和生成器有什么区别?