- Деструкторы в Python: уничтожение объектов
- Python Destructors to Destroy the Object
- Table of contents
- What is Destructor in Python?
- Create Destructor using the __del__() Method
- Important Points to Remember about Destructor
- Cases when Destructor doesn’t work Correctly
- Circular Referencing
- Exception in __init__ Method
- Summary and Quick Recap
- About Vishal
- Related Tutorial Topics:
- Python Exercises and Quizzes
Деструкторы в Python: уничтожение объектов
Пользователи вызывают Деструктор для уничтожения объекта. В Python разработчики могут не нуждаться в деструкторах в той степени, в которой они необходимы в языке C ++. Это связано с тем, что в Python есть сборщик мусора, функция которого автоматически обрабатывает управление памятью.
В этой статье мы обсудим, как работают деструкторы в Python и когда пользователи могут их использовать.
Функция __del __() используется в Python как функция деструктора. Пользователь может вызвать функцию __del __(), когда все ссылки на объект будут удалены, и он станет сборщиком мусора.
def __del__(self): # the body of destructor will be written here.
Пользователи также должны учитывать, что ссылка на объекты также удаляется, когда объект выходит из ссылки или когда заканчивается код.
В следующем примере мы будем использовать функцию __del __() и ключевое слово del для удаления всех ссылок на объект, чтобы деструктор включился автоматически.
# we will illustrate destructor function in Python program # we will create Class named Animals class Animals: # we will initialize the class def __init__(self): print('The class called Animals is CREATED.') # now, we will Call the destructor def __del__(self): print('The destructor is called for deleting the Animals.') object = Animals() del object
The class called Animals is CREATED. The destructor is called for deleting the Animals.
В приведенном выше коде деструктор вызывается при удалении ссылок на объект или после завершения программы. Это означает, что счетчик ссылок для объекта становится нулевым не тогда, когда объект выходит за пределы области видимости.
Мы также можем заметить, что деструктор вызывается после завершения программы.
# We will create Class named Animals class Animals: # Initialize the class def __init__(self): print('The class called Animals is CREATED.') # now, we will Call the destructor def __del__(self): print('The destructor is called for deleting the Animals.') def Create_object(): print('we are creating the object') object = Animals() print('we are ending the function here') return object print('we are calling the Create_object() function now') object = Create_object() print('The Program is ending here')
we are calling the Create_object() function now we are creating the object The class called Animals is CREATED. we are ending the function here The Program is ending here The destructor is called for deleting the Animals.
Теперь в следующем примере мы увидим, что когда вызывается функция(), она создает экземпляр класса Zebra, который передает себя классу Lion, который затем установит ссылку на класс Zebra, и будет иметь в результате циркулярную ссылку.
class Animals: # we will initialize the class def __init__(self): print(' The class called Animals is CREATED.') class Lion: def __init__(self, zebraa): self.zebra = zebraa class Zebra: def __init__(self): self.lion = Lion(self) def __del__(self): print("Zebra is dead") def function(): zebra = Zebra() function()
Как правило, сборщик мусора Python, который используется для обнаружения этих типов циклических ссылок, также удаляет ссылку. Но в приведенном выше примере пользовательский деструктор используется для пометки этого элемента как не подлежащего сбору.
Проще говоря, это означает, что сборщик мусора не знает порядка, в котором объект должен быть уничтожен, поэтому он их оставляет. Таким образом, если экземпляры пользователей задействованы в этой циклической ссылке, они будут храниться в памяти до тех пор, пока приложение будет работать.
В этой статье мы объяснили функцию деструкторов в Python и то, как пользователи могут использовать их для удаления объектов, ссылки на которые уже удалены из памяти.
Python Destructors to Destroy the Object
Destructor is a special method that is called when an object gets destroyed. On the other hand, a constructor is used to create and initialize an object of a class.
After reading this article, you will learn:
- How create a destructor in Python
- The use of __del__() method
- Wokring of a destructor
Table of contents
What is Destructor in Python?
In object-oriented programming, A destructor is called when an object is deleted or destroyed. Destructor is used to perform the clean-up activity before destroying the object, such as closing database connections or filehandle.
Python has a garbage collector that handles memory management automatically. For example, it cleans up the memory when an object goes out of scope.
But it’s not just memory that has to be freed when an object is destroyed. We must release or close the other resources object were using, such as open files, database connections, cleaning up the buffer or cache. To perform all those cleanup tasks we use destructor in Python.
The destructor is the reverse of the constructor. The constructor is used to initialize objects, while the destructor is used to delete or destroy the object that releases the resource occupied by the object.
In Python, destructor is not called manually but completely automatic. destructor gets called in the following two cases
In Python, The special method __del__() is used to define a destructor. For example, when we execute del object_name destructor gets called automatically and the object gets garbage collected.
Create Destructor using the __del__() Method
The magic method __del__() is used as the destructor in Python. The __del__() method will be implicitly invoked when all references to the object have been deleted, i.e., is when an object is eligible for the garbage collector.
This method is automatically called by Python when the instance is about to be destroyed. It is also called a finalizer or (improperly) a destructor.
Syntax of destructor declaration
def __del__(self): # body of a destructor
- def : The keyword is used to define a method.
- __del__() Method: It is a reserved method. This method gets called as soon as all references to the object have been deleted
- self : The first argument self refers to the current object.
Note: The __del__() method arguments are optional. We can define a destructor with any number of arguments.
Let’s see how to create a destructor in Python with a simple example. In this example, we’ll create a Class Student with a destructor. We’ll see: –
class Student: # constructor def __init__(self, name): print('Inside Constructor') self.name = name print('Object initialized') def show(self): print('Hello, my name is', self.name) # destructor def __del__(self): print('Inside destructor') print('Object destroyed') # create object s1 = Student('Emma') s1.show() # delete object del s1
Inside Constructor Object initialized Hello, my name is Emma Inside destructor Object destroyed
As you can see in the output, the __del__() method get called automatically is called when we deleted the object reference using del s1 .
In the above code, we created one object. The s1 is the reference variable that is pointing to the newly created object.
The destructor has called when the reference to the object is deleted or the reference count for the object becomes zero
Important Points to Remember about Destructor
- The __del__ method is called for any object when the reference count for that object becomes zero.
- The reference count for that object becomes zero when the application ends, or we delete all references manually using the del keyword.
- The destructor will not invoke when we delete object reference. It will only invoke when all references to the objects get deleted.
Let’s understand the above points using the example.
- First create object of a student class using s1 = student(‘Emma’)
- Next, create a new object reference s2 by assigning s1 to s2 using s2=s1
- Now, both reference variables s1 and s2 point to the same object.
- Next, we deleted reference s1
- Next, we have added 5 seconds of sleep to the main thread to understand that destructors only invoke when all references to the objects get deleted.
import time class Student: # constructor def __init__(self, name): print('Inside Constructor') self.name = name def show(self): print('Hello, my name is', self.name) # destructor def __del__(self): print('Object destroyed') # create object s1 = Student('Emma') # create new reference # both reference points to the same object s2 = s1 s1.show() # delete object reference s1 del s1 # add sleep and observe the output time.sleep(5) print('After sleep') s2.show()
Inside Constructor Hello, my name is Emma
After Sleep
After sleep Hello, my name is Emma Object destroyed
- As you can see in the output destructors only invoked when all references to the objects get deleted.
- Also, the destructor is executed when the code (application) ends and the object is available for the garbage collector. (I.e., we didn’t delete object reference s2 manually using del s2 ).
Cases when Destructor doesn’t work Correctly
The _ _del__ is not a perfect solution to clean up a Python object when it is no longer required. In Python, the destructor behave behaves weirdly and doesn’t execute in the following two cases.
- Circular referencing when two objects refer to each other
- Exception occured in __init__() method
Circular Referencing
The __del()__() doesn’t work correctly in the case of circular referencing. In circular referencing occurs when two objects refer to each other.
When both objects go out of scope, Python doesn’t know which object to destroy first. So, to avoid any errors, it doesn’t destroy any of them.
In short, it means that the garbage collector does not know the order in which the object should be destroyed, so it doesn’t delete them from memory.
Ideally, the destructor must execute when an object goes out of scope, or its reference count reaches zero.
But the objects involved in this circular reference will remain stored in the memory as long as the application will run.
In the below example, ideally, both Vehicle and Car objects must be destroyed by the garbage collector after they go out of scope. Still, because of the circular reference, they remain in memory.
I’d recommend using Python’s with statement for managing resources that need to be cleaned up.
import time class Vehicle(): def __init__(self, id, car): self.id = id; # saving reference of Car object self.dealer = car; print('Vehicle', self.id, 'created'); def __del__(self): print('Vehicle', self.id, 'destroyed'); class Car(): def __init__(self, id): self.id = id; # saving Vehicle class object in 'dealer' variable # Sending reference of Car object ('self') for Vehicle object self.dealer = Vehicle(id, self); print('Car', self.id, 'created') def __del__(self): print('Car', self.id, 'destroyed') # create car object c = Car(12) # delete car object del c # ideally destructor must execute now # to observe the behavior time.sleep(8)
Vehicle 12 created Car 12 created
Exception in __init__ Method
In object-oriented programming, A constructor is a special method used to create and initialize an object of a class. using the __init__() method we can implement a constructor to initialize the object.
In OOP, if any exception occurs in the constructor while initializing the object, the constructor destroys the object.
Likewise, in Python, if any exception occurs in the init method while initializing the object, the method del gets called. But actually, an object is not created successfully, and resources are not allocated to it
even though the object was never initialized correctly, the del method will try to empty all the resources and, in turn, may lead to another exception.
class Vehicle: def __init__(self, speed): if speed > 240: raise Exception('Not Allowed'); self.speed = speed; def __del__(self): print('Release resources') # creating an object car = Vehicle(350); # to delete the object explicitly del car
Traceback (most recent call last): Release resources Exception: Not Allowed
Summary and Quick Recap
- In object-oriented programming, A destructor is called when an object is deleted or destroyed.
- Destructor is used to perform the clean-up activity before destroying the object, such as closing database connections or filehandle.
- In Python we use __del__() method to perform clean-up task before deleting the object.
- The destructor will not invoke when we delete object reference. It will only invoke when all references to the objects get deleted.
Did you find this page helpful? Let others know about it. Sharing helps me continue to create free Python resources.
About Vishal
I’m Vishal Hule, Founder of PYnative.com. I am a Python developer, and I love to write articles to help students, developers, and learners. Follow me on Twitter
Related Tutorial Topics:
Python Exercises and Quizzes
Free coding exercises and quizzes cover Python basics, data structure, data analytics, and more.
- 15+ Topic-specific Exercises and Quizzes
- Each Exercise contains 10 questions
- Each Quiz contains 12-15 MCQ