gpt4 book ai didi

python - 如何防止模块被垃圾收集器删除或在 __del__ 方法内重新导入

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

我为日志记录模块编写了一个包装类,它具有 __del__ 方法来在程序末尾删除日志文件。

我的程序将此日志文件从其他类复制到存档中,并且在下一个程序执行之前工作文件夹中没有日志文件很重要。但我无法从其他模块中删除它,因为它们仍然由记录器处理。

所以我为此使用了 __del__ 方法。

def __del__(self):
if self.config_object.logfile is not None:
import os
try:
os.unlink(self.config_object.logfile)
except (WindowsError, AttributeError):
pass

我重新导入 os,因为有时 in 已在我的 Logging 类之前被垃圾收集器销毁。这在 python3.2 中工作正常

但是切换到 python3.4 后我看到了这样的错误:

  File "<frozen importlib._bootstrap>", line 2236, in _find_and_load
File "<frozen importlib._bootstrap>", line 263, in __enter__
File "<frozen importlib._bootstrap>", line 287, in _get_module_lock
File "<frozen importlib._bootstrap>", line 173, in __init__
TypeError: 'NoneType' object is not callable

我尝试阻止操作系统删除而不是重新导入操作系统,但失败了。

我尝试过这个想法:使用内部 os 创建循环引用。在我的类(class)中添加带有 os 模块的字段。直接调用 gc.disabled()。但他们都没有帮助。

所以我有两个问题。第一个是当 python 程序被垃圾收集器销毁时,如何使用新的 importlib 重新导入 python 3.4 中的操作系统。其次是如何防止垃圾收集器删除 os 模块。

附注我知道使用上下文管理器比 __del__ 更好,并阅读有关此 iat SO 的问题。当然,我可以更改程序逻辑以避免删除日志文件。所以这个log的问题只是一个例子,唤醒了我的好奇心。如果有人能证明我的两个目标都是不可能的,那就可以了,也是最好的答案。但是,如果存在一个丑陋且非Pythonic的解决方案,我想知道它,即使它正在以某种方式直接改变字节码或类似的东西。

最佳答案

您可以将对 os.unlink() 函数的引用绑定(bind)为默认参数,因此当 Hook 运行时您仍然可以访问该函数:

def __del__(self, _os_unlink=os.unlink):
if self.config_object.logfile is not None:
import os
try:
_os_unlink(self.config_object.logfile)
except (WindowsError, AttributeError):
pass

但是,请考虑到永远无法保证钩子(Hook)在 Python 关闭时执行。

此外,如果您需要调用碰巧在纯 python 中实现的其他函数,那么您需要考虑这些函数也可能使用已设置为 None 的依赖项此时。您可能必须使用“捕获的”引用重新实现这些函数,或者必须为您的调用恢复依赖项。例如,os.path.exists() 需要 os.stat() 仍然可用。要么用捕获的 genericpath.exists() 重新实现 os.stat function,要么至少在调用捕获的 os.stat 函数之前确保 os.path.exists() 存在。

关于python - 如何防止模块被垃圾收集器删除或在 __del__ 方法内重新导入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30122737/

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