我正在尝试做以下事情:
self.sender = None # type: 'Node'
我无法导入节点,因为我会得到一个循环。所以我用这里提到的引号写它 http://mypy.readthedocs.io/en/latest/common_issues.html#import-cycles 但我仍然收到以下错误
error: Name 'Node' is not defined
有什么解决办法吗?
谢谢!
我正在尝试做以下事情:
self.sender = None # type: '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 解析。这就是 mypymymodule.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