#python #python-3.x #memory-leaks #garbage-collection #python-3.6
#python #python-3.x #утечки памяти #сбор мусора #python-3.6
Вопрос:
У меня есть скрипт, в котором я создаю объект в облаке с помощью API и хочу удалять его в некоторых случаях в конце скрипта.
class ObjCreator():
def __init__(self, keep_object: bool):
self.keep_object = keep_object
print("init")
def create_object(self):
print("Created object using API")
def delete_object(self):
print("Deleting object using API")
def __del__(self):
print("Deleting object using API only if keep_object is False")
if not self.keep_object:
self.delete_object()
Я видел некоторые утечки памяти в программах на Python, поэтому очевидно, что GC не является префектом (т. Е. Не подлежащими сбору объектами).
Я боюсь, что переопределение функции del приведет к утечке памяти. Возможно ли это? Если да, то есть ли у вас какие-либо предложения по другому, элегантному решению?
Комментарии:
1. Добро пожаловать в SO! Просто обратите внимание, вы не перегружаете его, вы переопределяете его, возможно, это могло бы помочь с поиском ответа в Google
2. Дополнительная подсказка: для работы всех этих методов требуется добавленный параметр
self
— это ссылка на вызывающий класс, который Python передает явно!3. Привет, спасибо 🙂 Я случайно пропустил self, когда писал упрощение кода для этого вопроса. Исправлено.
Ответ №1:
Ваша интуиция верна, переопределение __del__
метода означает, что метод базового класса __del__
больше не вызывается автоматически (хотя я не думаю, что здесь вероятна утечка памяти). На самом деле в документации явно упоминается это:
Если базовый класс имеет метод __del__(), метод __del__() производного класса, если таковой имеется, должен явно вызывать его, чтобы обеспечить надлежащее удаление части экземпляра базового класса.
Пример кода для этого из репозитория CPython:
def __del__(self):
# ... your cleanup code here ...
super().__del__() # call to base class
Комментарии:
1. Это имеет значение только в том случае, если у суперкласса действительно есть
__del__
метод. В частности,object
не имеет__del__
.2. В вашем примере класс является наследником. Почему это должно работать, когда нет суперкласса?
3. Если вы попытаетесь вызвать
super().__del__
, когда нет суперкласса__del__
для делегирования, вы получите AttributeError .4. @user2357112supportsMonica вот почему я не понял ответа. Рассмотрим случай, когда вы добавляете новые атрибуты к наследнику — они не будут удалены с помощью super() .__del__()
5. @xjcl — тогда зачем вообще вызывать метод super?