Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does python always call __del__ synchronously?

Tags:

python

The python documentation for __del__ explains that an object's __del__ method can be called when its reference count is reduced to zero. Is it always called immediately (i.e. synchronously)? Or is it possible that the __del__ method will be called "at some point in the future"?

Furthermore, does the answer to this question apply to Python in general? Or is some latitude granted to the language implementation? (I use CPython.)

For this question, assume the following:

  • The objects in question inherit from object.
  • The objects in question have a custom __del__ implementation.
  • The objects' custom __del__ implementation does NOT create new references to any objects.
  • The objects in question are NOT part of a reference cycle.
  • The interpreter is not in the process of shutting down.

From what I can tell, there seems to be a lot of confusion around this topic. In an effort to side-step some unnecessary discussion, let me give some examples of unacceptable answers:

  • "Don't use __del__! It's confusing!"
  • "Don't use __del__! It's not 'pythonic'."
  • "Don't use __del__, use a context manager instead."
  • Any answer that makes an assertion about what is or isn't guaranteed without citing a credible source. (Please feel free to cite other SO answers, but don't rely on them as your sole source. "Credible" in this instance means something from the documentation, or a reputable person, or maybe even the CPython source itself.)

To rephrase this question with an example, consider this code:

class C(object):
    def __init__(self, i):
        self.i = i

    def __del__(self):
        print "C.__del__:", self.i

print "Creating list"
l = [C(0), C(1), C(2)]

print "Popping item 1"
l.pop(1)

print "Clearing list"
l = []

print "Exiting..."

which produces the following output:

$ python test_del.py
Creating list
Popping item 1
C.__del__: 1
Clearing list
C.__del__: 2
C.__del__: 0
Exiting...

Notice that in this example, __del__ was called synchronously. Is that behavior guaranteed by the language? (Keep in mind the assumptions listed above.)

like image 223
Stuart Berg Avatar asked May 07 '26 00:05

Stuart Berg


1 Answers

From The Python Language Reference (Python 2.7.3 edition), Chapter 3, Data model:

Objects are never explicitly destroyed; however, when they become unreachable they may be garbage-collected. An implementation is allowed to postpone garbage collection or omit it altogether — it is a matter of implementation quality how garbage collection is implemented, as long as no objects are collected that are still reachable.

CPython implementation detail: CPython currently uses a reference-counting scheme with (optional) delayed detection of cyclically linked garbage, which collects most objects as soon as they become unreachable, but is not guaranteed to collect garbage containing circular references. See the documentation of the gc module for information on controlling the collection of cyclic garbage. Other implementations act differently and CPython may change. Do not depend on immediate finalization of objects when they become unreachable (ex: always close files).

like image 144
Jonathan Callen Avatar answered May 09 '26 13:05

Jonathan Callen