Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

On second initialization of an object, why is __init__ called before __del__?

Tags:

python

oop

Consider the following example code

class A:
    def __init__(self, i):
        self.i = i
        print("Initializing object {}".format(self.i))

    def __del__(self):
        print("Deleting object {}".format(self.i))

for i in [1, 2]:
    a = A(i)

Creating the object within the loop was intended to assure that the destructor of A would be called before the new A object would be created. But apparently the following happens:

Initializing object 1

Initializing object 2

Deleting object 1

Deleting object 2

Why is the destructor of object 1 only called after the new object has been initialized? Is this an intended behaviour? I know that the for loop has no own scope in python. In C++, for example, the destructor of 1 would certainly be called before the constructor for object 2 (at least if the object is declared within the loop).

In my program I want to assure that the old object is deleted before the new one is created. Is there another possibility apart from deleting a explicitly at the end of the for loop?

Thanks in advance.

like image 550
shark.dp Avatar asked Apr 18 '11 12:04

shark.dp


People also ask

What is the purpose of the __ init __ method?

The __init__ method lets the class initialize the object's attributes and serves no other purpose. It is only used within classes.

Which function will be executed implicitly before the __ init __ method is called?

Method __init__ will be called once __new__ method completed execution. You can create new instance of the class by invoking the superclass's __new__ method using super.

When Init method is called in Python?

__init__ method It is called as a constructor in object oriented terminology. This method is called when an object is created from a class and it allows the class to initialize the attributes of the class.

What is def __ init __( self in Python?

__init__ is one of the reserved methods in Python. In object oriented programming, it is known as a constructor. The __init__ method can be called when an object is created from the class, and access is required to initialize the attributes of the class.


2 Answers

Creation of the second object happens before the name is rebound and the first object is disposed of.

  1. The first A is instantiated.
  2. a is bound.
  3. The second A is instantiated.
  4. a is rebound, and the first A is disposed of.
  5. The program ends, and the second A is disposed of.
like image 199
Ignacio Vazquez-Abrams Avatar answered Oct 26 '22 19:10

Ignacio Vazquez-Abrams


You can't rely on the garbage collector's implementation details when planning lifetime dependencies. You need to do this explicitly one way or another.

Context managers spring to mind, for example:

from contextlib import contextmanager

@contextmanager
def deleting(obj):
    try:
        yield
    finally:
        del(obj)

class A:
    def __init__(self, i):
        self.i = i
        print("Initializing object {}".format(self.i))

    def __del__(self):
        print("Deleting object {}".format(self.i))

for i in [1,2]:
    with deleting(A(i)) as obj:
        pass

print

for i in [1,2]:
    a = A(i)

This produces the following output:

Initializing object 1
Deleting object 1
Initializing object 2
Deleting object 2

Initializing object 1
Initializing object 2
Deleting object 1
Deleting object 2
like image 33
David Heffernan Avatar answered Oct 26 '22 19:10

David Heffernan