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

问题描述 投票:0回答:1
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__完成执行之前如何调用析构函数。

python python-3.x destructor
1个回答
0
投票

问题是您的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
© www.soinside.com 2019 - 2024. All rights reserved.