Python graphlib调用static_order()未触发CycleError原因
问题描述
学习Python 3.9版本提供的graphlib模块时,尝试构造循环依赖场景触发CycleError异常,最初编写的代码如下,运行后并未抛出预期的异常:
#!/usr/bin/python3 from graphlib import TopologicalSorter ts = TopologicalSorter() ts.add(2, 1) ts.add(3, 2) ts.add(4, 3) ts.add(1, 4) ts.static_order()
将代码修改为如下形式,把ts.static_order()的返回结果转换为tuple(转换为list效果一致)后,就能成功触发CycleError,需要明确该现象的产生原因:
#!/usr/bin/python3 from graphlib import TopologicalSorter ts = TopologicalSorter() ts.add(2, 1) ts.add(3, 2) ts.add(4, 3) ts.add(1, 4) tuple(ts.static_order()) # 为什么转成tuple/list就能触发异常?
核心原因
造成这个差异的根本原因是TopologicalSorter.static_order()的返回值是惰性求值的迭代器对象:
- 仅调用
ts.static_order()时,程序只会完成迭代器对象的初始化创建,不会执行迭代器内部的拓扑排序计算、循环依赖检测逻辑,自然不会触发CycleError。 - 当使用
tuple()、list()这类可迭代对象构造方法处理返回值时,程序会完整遍历迭代器生成所有元素,这个过程才会真正执行拓扑排序的全流程计算,检测到构造出的1→2→3→4→1循环依赖后,就会正常抛出CycleError。
补充:只要触发了迭代器的遍历逻辑,不管是转list/tuple、还是用for循环迭代、还是用
next()逐个取值,走到环检测的逻辑节点时都会抛出异常,和是否转成容器类型没有直接关系。比如下面的写法同样会触发异常:# 遍历迭代器,同样会触发CycleError for node in ts.static_order(): print(node)
内容的提问来源于stack exchange,提问作者ChsharpNewbie
相关产品推荐
相关产品推荐

