我说的是这个问题: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模块能做到这一点吗?
发布于 2022-12-04 04:01:09
是的,使用gc模块,我们可以检查是否有(新的)异常仅由跟踪帧引用。
在实践中,迭代gc对象会创建一个额外的引用程序(不能将WeakSet作为内置异常使用--内置的异常不支持弱引用),因此我们检查是否有两个引用器--框架和附加引用程序。
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())发布于 2022-12-02 19:15:15
我相信你可以使用gc模块来做这样的事情。
import gc
# First, enable garbage collection
gc.enable()
# Save an exception to a variable
exception = Exception('test exception')
# Check for objects that are no longer being referenced by the program
if gc.garbage:
# Print the objects that are causing the cycle
print(gc.garbage)
# Use the gc.get_referrers method to find out what objects
# are causing the cycle
for obj in gc.garbage:
print(gc.get_referrers(obj))
# Modify your code to break the cycle
# (This will depend on your specific code and the objects
# involved in the cycle)https://stackoverflow.com/questions/67157372
复制相似问题