class foo:
def __del__(self):
import os
p = foo()
Run Code Online (Sandbox Code Playgroud)
这导致了导入错误
Exception ignored in: <function foo.__del__ at 0x000001DF9986DE50>
Traceback (most recent call last):
File "C:\Users\chen\PycharmProjects\pythonProject\main.py", line 3, in __del__
ImportError: sys.meta_path is None, Python is likely shutting down
Run Code Online (Sandbox Code Playgroud)
我只是用这个例子来演示问题所在,我需要在del中导入库,这可以实现吗?
根据__del__文档:
警告 - 由于
__del__()调用方法的情况不稳定,执行期间发生的异常将被忽略,而是打印警告sys.stderr。尤其:
__del__()可以在执行任意代码时调用,包括从任意线程执行任意代码。如果__del__()需要锁定或调用任何其他阻塞资源,则可能会死锁,因为资源可能已被中断执行的代码占用__del__()。__del__()可以在解释器关闭期间执行。因此,它需要访问的全局变量(包括其他模块)可能已被删除或设置为None. Python 保证在删除其他全局变量之前,先从其模块中删除名称以单下划线开头的全局变量;如果不存在对此类全局变量的其他引用,这可能有助于确保调用该方法时导入的模块仍然可用__del__()。
要点是,__del__不可靠(第#1点意味着你可能会遇到模块导入锁的问题,第#2点意味着每个该死的东西都可能在关闭期间损坏),并且当解释器关闭时,你不能,也不应该' t,期望能够导入任何东西。解决方案是避免__del__(正如您所见,这是相当不可靠的)而支持更具确定性的东西,例如使用and和 using语句为您的类实现上下文管理器协议,因此清理发生在确定性的时间点(在解释器关闭)。__enter____exit__with
或者,不要推迟导入,并将它们缓存在不会被清除的地方,例如使用以下黑客:
import os # Deferred imports are usually a bad idea anyway
class foo:
def __del__(self, os=os): # Fake argument with default caches os separate from globals
# do stuff with os cached in location it definitely won't be preemptively cleared
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
744 次 |
| 最近记录: |