我正在尝试实现图的节点和边。这是我的代码:
from typing import NamedTuple, List
class Node(NamedTuple):
name: str
edges: List[Edge]
class Edge(NamedTuple):
src: Node
dest: Node
这会引发错误,因为创建
Edge
时未定义
Node
类型。
NameError: name 'Edge' is not defined
切换定义不起作用,因为
Edge
也引用
Node
我怎样才能让它发挥作用?
你遇到的问题是 Python 中类定义的常见问题,而不仅仅是类型提示或命名元组。你无法以相互依赖的方式定义
Node
和
Edge
,因为一个类的定义在另一个类的定义完成之前不可用。
你可以使用 Python 3.7+ 中的
typing.ForwardRef
来解决这个问题:
from typing import NamedTuple, List, ForwardRef
class Edge(NamedTuple):
src: 'Node'
dest: 'Node'
class Node(NamedTuple):
name: str
edges: List[Edge]
这告诉 Python 解释器
'Node'
在
Edge
的定义中是一个对稍后将定义的类的“前向引用”。
对于 Python 3.6,
typing.ForwardRef
不可用。
作为一种解决方法,你可以使用字符串文字作为对尚未定义的类的注释:
from typing import NamedTuple, List
class Node(NamedTuple):
name: str
edges: List['Edge'] # 使用字符串文字 'Edge'
class Edge(NamedTuple):
src: 'Node' # 使用字符串文字 'Node'
dest: 'Node'
虽然这在 Python 3.6 中有效,但建议尽可能使用 Python 3.7+ 并使用
typing.ForwardRef
来获得更清晰和更易读的代码。