четверг, 8 марта 2012 г.

del x и x.__del__()

Залез я сегодня на сайт Яндекса и посмотрел, какие задачи даются для проверки знаний на Python. И уже первая вызвала у меня затруднения)) Вот она:
Что выведет следующий код:


class A:
     def __init__(self, name):
          self.name = name
     def __del__(self):
          print self.name

aa = [A(str(i)) for i in range(3)]
for a in aa:
    del a
print 'done'

Я-то грешным умом подумал сперва, что вывод будет такой: 0 1 2 3 done. Однако не всё оказалось так просто! Возможно, это очевидно для более продвинутых программистов, но меня изрядно удивило. Проверив код на Python 2.7 я получил только done, что и заставило меня задуматься.
Конечно, первым делом я полез в документацию __del__(self) и вот что я там увидел:
Заметка:
del x не является прямым вызовом x.__del__() - первая форма сокращает количество ссылок на объект x на одну, тогда как последний метод вызывается только когда количество ссылок достигает нуля...
Однако, это не прояснило для меня ситуацию: в конце-то концов у меня же нет больше ссылок не объекты в списке! Но, присмотревшись повнимательнее, я понял, что это не так: в цикле как раз и создается новая ссылка на каждый объект из списка, и эта-то ссылка не объект удаляется инструкцией del, но другая ссылка, которая хранится в списке остаётся. Потому-то и не вызывается нужный мне метод.
Импортировав модуль sys я в этом и убедился. Причём, как можно заметить, если присвоить  переменной aa новое значение, то будет вызван метод __del__().

Комментариев нет:

Отправить комментарий