在初始化 (__init__) 完成之前调用的析构函数 (__del__)

Destructor (__del__) called before initialization (__init__) complete

class MyClass:
    def __init__(self):
        print("HEYYYYYYYYYY") # prints
        file = open("really_cool_file.txt")
        print("HOOOOOOOOOOOO") # does **NOT** print
        self._f = file
        print("WADUP!!!!!!!!!!") # does **NOT** print
        print(hasattr(self, "_f"))

    def __del__(self):
        print("closing any open files ")
        self._f.close()


my_instance = MyClass()
print("33333333333") # NEVER PRINTS

控制台输出如下:

HEYYYYYYYYYY
closing any open files 

我们收到以下错误消息:

C:\Users\Sam\AppData\Local\Programs\Python\Python38-32\python.exe 
H:/PYTHON_RECORD_VIDEO/dffhsrthrth.py
Traceback (most recent call last):
  File "H:/PYTHON_RECORD_VIDEO/dffhsrthrth.py", line 15, in <module>

    my_instance = MyClass()

  File "H:/PYTHON_RECORD_VIDEO/dffhsrthrth.py", line 4, in __init__
    file = open("really_cool_file.txt")
FileNotFoundError: [Errno 2] No such file or directory: 'really_cool_file.txt'
Exception ignored in: <function MyClass.__del__ at 0x0383D1D8>
Traceback (most recent call last):
  File "H:/PYTHON_RECORD_VIDEO/dffhsrthrth.py", line 12, in __del__
    self._f.close()
AttributeError: 'MyClass' object has no attribute '_f'

Process finished with exit code 1

self._f = file 行之前调用析构函数 __init__ 我不明白在 __init__ 完成执行之前如何调用析构函数。

问题是您的 open 呼叫失败;该异常导致 __init__ 的其余部分被跳过(它直接冒泡而不执行初始化程序的其余部分),但 __init__ 只是初始化程序,而不是构造函数,因此 __del__ 必须清理对象时仍会调用。由于您未能分配给 self._f,终结器无法找到它。

__del__ 中引发的异常会被记录并忽略(因为它们不会以可预测的方式发生,所以没有安全的方法来处理它们),所以这不会破坏您的程序,只要捕获并处理打开文件的异常。

如果您想在这种情况下保持弹性(以避免第二条错误消息),只需使 __del__ 更具弹性:

def __del__(self):
    print("closing any open files ")
    try:
        self._f.close()
    except AttributeError:
        pass  # Exception in constructor won't initialize _f; ignore it