简体   繁体   English

__del__ 中的 python 导入错误,如何解决?

[英]python ImportError in __del__ ,how to solve this?

class foo:
    def __del__(self):
        import os

p = foo()

This caused an import error这导致了导入错误

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

I'm only using this example to demostrate what's wrong, I need to import libraries in del ,is that achievable?我只是用这个例子来演示什么是错的,我需要在del中导入库,这可以实现吗?

Per the __del__ docs :根据__del__文档

Warning - Due to the precarious circumstances under which __del__() methods are invoked, exceptions that occur during their execution are ignored, and a warning is printed to sys.stderr instead.警告 - 由于调用__del__()方法的不稳定环境,在它们执行期间发生的异常将被忽略,并且会向sys.stderr打印警告。 In particular:尤其是:

  • __del__() can be invoked when arbitrary code is being executed, including from any arbitrary thread. __del__()可以在执行任意代码时调用,包括从任意线程执行。 If __del__() needs to take a lock or invoke any other blocking resource, it may deadlock as the resource may already be taken by the code that gets interrupted to execute __del__() .如果__del__()需要获取锁或调用任何其他阻塞资源,它可能会死锁,因为该资源可能已经被中断执行__del__()的代码占用。
  • __del__() can be executed during interpreter shutdown. __del__()可以在解释器关闭期间执行。 As a consequence, the global variables it needs to access (including other modules) may already have been deleted or set to None .因此,它需要访问的全局变量(包括其他模块)可能已经被删除或设置为None Python guarantees that globals whose name begins with a single underscore are deleted from their module before other globals are deleted; Python 保证在删除其他全局变量之前从其模块中删除名称以单个下划线开头的全局变量; if no other references to such globals exist, this may help in assuring that imported modules are still available at the time when the __del__() method is called.如果不存在对此类全局变量的其他引用,这可能有助于确保在__del__()方法时导入的模块仍然可用。

Point is, __del__ is not reliable (point #1 means you could have issues with the module import lock, point #2 means every damn thing can break during shutdown), and when the interpreter is shutting down, you can't, and shouldn't, expect to be able to import anything.要点是, __del__不可靠(第 1 点意味着您可能遇到模块导入锁定问题,第 2 点意味着在关闭期间所有该死的东西都可能中断),并且当解释器关闭时,您不能,而且应该't,期望能够导入任何东西。 The solution is to avoid __del__ (which is fairly unreliable as you've seen) in favor of something more deterministic, like implementing the context manager protocol for your class with __enter__ and __exit__ and using with statements, so cleanup occurs at a deterministic point in time (prior to interpreter shutdown).解决方案是避免__del__ (正如您所见,这是相当不可靠的),而采用更具确定性的方法,例如使用__enter____exit__并使用with语句为您的 class 实现上下文管理器协议,因此清理发生在确定性点时间(在解释器关闭之前)。

Alternatively, don't defer your imports, and cache them somewhere they won't get cleared, eg with hacks like:或者,不要推迟您的导入,并将它们缓存在它们不会被清除的地方,例如使用以下技巧:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM