gpt4 book ai didi

python - 如何测试由保存的异常引起的引用循环?

转载 作者:行者123 更新时间:2023-12-05 04:50:55 24 4
gpt4 key购买 nike

我说的是这个问题:https://bugs.python.org/issue36820 .

小总结:

保存异常会导致循环引用,因为异常的数据包括一个回溯,其中包含堆栈帧和保存异常的变量。

try:
1/0
except Exception as e:
ee = e

代码没有被破坏,因为 Python 最终会用它的垃圾收集器释放内存。但是整个情况是可以避免的:

try:
1/0
except Exception as e:
ee = e
...
...
finally:
ee = None

在链接的 bpo-36820 中有一个演示,其中保持了一个弱引用。

我的问题是是否存在不需要编辑函数本身的测试。有点像

  • 运行测试函数
  • 检查是否创建了新的循环

gc 模块可以做到吗?

最佳答案

是的,使用 gc 模块,我们可以检查是否存在仅由回溯帧引用的(新)异常。

在实践中,迭代 gc 对象会创建一个额外的引用(不能使用 WeakSet 因为内置异常不支持 weakref),所以我们检查那里是两个引荐来源网址 — 框架和附加引荐来源网址。

def get_exception_ids_with_reference_cycle(exclude_ids=None):
import gc
import types
exclude_ids = () if exclude_ids is None else exclude_ids
exceptions = [
o for o in gc.get_objects(generation=0)
if isinstance(o, Exception) and id(o) not in exclude_ids
]
exception_ids = [
id(e) for e in exceptions
if len(gc.get_referrers(e)) == 2 and all(
isinstance(r, types.FrameType) or r is exceptions
for r in gc.get_referrers(e)
)
]
return exception_ids

用法:

exception_ids = get_exception_ids_with_reference_cycle()
x()
print(bool(get_exception_ids_with_reference_cycle(exclude_ids=exception_ids)))

替代用法:

@contextlib.contextmanager
def make_helper():
exception_ids = get_exception_ids_with_reference_cycle()
yield lambda: bool(get_exception_ids_with_reference_cycle(exclude_ids=exception_ids))


with make_helper() as get_true_if_reference_cycle_was_created:
x()
print(get_true_if_reference_cycle_was_created())

关于python - 如何测试由保存的异常引起的引用循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67157372/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com