__del__ on exit behavior
Asked Answered
F

1

4

I have some test.py file:

class A:
    def __init__(self):
        print("A init")

    def __del__(self):
        print("A del")

a = A()

When I run it 10 times (python3 test.py) it always produces next output:

A init
A del

But if I add sys.exit call to end of script:

import sys

class A:
    def __init__(self):
        print("A init")

    def __del__(self):
        print("A del")

a = A()

sys.exit(-1)

in 5 of 10 cases (randomly) i have

A init

and in second half of cases:

A init
A del    

I use Python3.4.3 [MSC v.1600 32 bit] on Windows 7 x64. So why __del__ method called not every time? Do I need to use some other exit method to pass return code of script and have all destructors guaranteed executed? And one more related question: is it possible to execute destructors on receive SIGTERM or SIGKILL from OS?

Fowkes answered 25/1, 2016 at 0:0 Comment(6)
If you want to guarantee the clean-up method gets called, consider a context manager.Loafer
You should almost never use __del__. You can catch signals with the signal module, except for SIGKILL, which can't be caught.Lais
Also, use sys.exit(0);, which means that the code worked properly.Teletypesetter
2L3viathan The thing why I want to use del, because I am writing wrapper to some .so library, which works with some OS audio resourses and it clearly says that I must call some deinit method on exit, or it may cause troubles when working with library on next launch which will be fixed only after reboot). So I want to call wrapper class in __del__. May be better decision to separate deinit in some other method and completely rely on users of wrapper?Fowkes
2AMACB I want to pass -1 as return code, only for exampleFowkes
@Lais except for SIGKILL and SIGSTOP*Inearth
B
4

From the documentation:

It is not guaranteed that __del__() methods are called for objects that still exist when the interpreter exits.

If you want to ensure that a.__del__ is invoked, you'll have to explicitly delete the instance:

a = A()
del a   # Assuming this is the final reference to the object
Blackguard answered 25/1, 2016 at 0:22 Comment(1)
It might be worth noting that calling del a doesn't necessarily mean that the object's __del__ method gets called. That's only sure if you're using CPython and there are no other references to the object. In other situations, it may be subject to the whims of the garbage collector.Juliusjullundur

© 2022 - 2024 — McMap. All rights reserved.