Есть ли способ, чтобы класс удалить экземпляр себя. Я знаю, что для переменных вы можете сделать del x, но как это сделать для классов? Если я сделаю что-то вроде:

class foo(object):
    x=5
    def __init__(self):
        print "hi"
    def __del__(self):
        del self
        print "bye"

a = foo()
a.__del__()
print a.x

Вывод кода:

hi
bye
5

Экземпляр foo не был удален. Есть ли способ заставить класс сделать это?

2
Ansh145 17 Дек 2015 в 04:33

3 ответа

Лучший ответ

Нет, если у вас есть ссылка на экземпляр класса, то по определению у него есть оставшиеся ссылки. Вы можете использовать ключевое слово del для удаления имени (освобождая ссылку от этого имени на объект), но если ссылка на экземпляр хранится в другом месте, экземпляр остается.

Если вы хотите использовать детерминированное поведение очистки, не используйте __del__ (который не является детерминированным очевидным или непротиворечивым способом и до Python 3.4 мог вызвать утечки ссылочного цикла, если какой-либо элемент цикла был экземпляром класса, который определил финализатор __del__. Пусть класс реализует протокол менеджера контекста и используйте экземпляры с {{ X2}} операторы для получения детерминированной очистки; экземпляр будет существовать до тех пор, пока не исчезнет последняя ссылка, но пока __exit__ выполняет необходимое освобождение ресурсов, пустая оболочка экземпляра почти ничего не стоит.

В качестве примера управления контекстом мы сделаем x атрибутом экземпляра foo, а не атрибутом класса, и мы скажем, что нам нужно убедиться, что ссылка экземпляра на x удалена в известное время (обратите внимание, потому что del просто удаляет нашу ссылку, если кто-то еще сохранил a.x, объект фактически не будет освобожден, пока не будут освобождены другие ссылки):

class foo(object):
    def __init__(self, x):
        self.x = x
        print "hi"
    def __enter__(self):
        return self
    def __exit__(self, exc_type, exc_val, exc_tb):
        print "bye"
        del self.x

with foo(123456789) as a:
    print a.x  # This works, because a.x still exists
# bye is printed at this point
print a.x # This fails, because we deleted the x attribute in __exit__ and the with is done
# a still exists until it goes out of scope, but it's logically "dead" and empty
0
ShadowRanger 17 Дек 2015 в 02:03

del a должен сделать трюк:

Код:

class foo(object):
    x=5
    def __init__(self):
        print "hi"
    def __del__(self):
        del self
        print "bye"

a = foo()
del a
print a.x

Выход:

$ python test.py
hi
here
bye
Traceback (most recent call last):
  File "test.py", line 12, in <module>
    print a.x
NameError: name 'a' is not defined
-1
asiviero 17 Дек 2015 в 01:40

Определяя __del__, я считаю, что вы переопределяете поведение по умолчанию del. Как вы можете прочитать здесь, __del__ называется когда счетчик ссылок на объект достигает 0. Не рекомендуется использовать __del__, если вы не знаете, что делаете.

РЕДАКТИРОВАТЬ: это неверно, пожалуйста, проверьте ответ shadowranger. Хотя ссылка все еще актуальна для Python 2

0
OnGle 17 Дек 2015 в 02:02