мне нужно сделать очистку объекта при удалении экземпляра, но не при выходе.может ли экземпляр удалить себя? - PullRequest
0 голосов
/ 25 августа 2010

Я хотел бы выполнить очистку всякий раз, когда экземпляр удаляется во время выполнения, но не во время сбора мусора, который происходит при выходе.

в примере ниже, когда c удаляется, файл удаляется, и это то, что я хочу; однако этот файл также удаляется при выходе из программы, и это НЕ то, что я хочу.

class C:
  def __del__(self):
    os.remove(self.filename)

c=C()
del c

Могу ли я связать удаление экземпляра среды выполнения с блоком операторов, но не выполнять этот же блок при выходе из Python?

спасибо.

Ответы [ 2 ]

4 голосов
/ 25 августа 2010

CPython использует подсчет ссылок и запускает только полноценный GC (который удаляет циклические ссылки) время от времени, c = C(); del c вызовет новый C, чтобы сразу же получить gc, да.Что касается __del__ и выхода интерпретатора, в документах говорится :

Не гарантируется, что методы __del__() вызываются для объектов, которые все еще существуют при выходе из интерпретатора.

Но, кажется, невозможно быть уверенным.Плюс (по общему признанию, это не имеет большого значения в практическом плане), другие реализации, такие как Jython и IronPython, не используют подсчет ссылок = уничтожение / завершение объекта менее предсказуемо (или - в теории - может вообще не произойти, по крайней мере, в .NET).

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

Возможно, вам понадобится менеджер контекста .

1 голос
/ 25 августа 2010

То, что вы хотите сделать, не настолько питонно (и я не думаю, что это возможно). Удаление экземпляров во время выполнения обычно не требуется.

Вы можете использовать свою собственную функцию вместо del во время выполнения:

def rem(object):
    object.__remove()

class C:
    def __remove(self):
        os.remove(self.filename)

c=C()
rem(c)

Или вы можете реализовать удаление как метод экземпляра (более питонно!):

class C:
    def remove(self):
        os.remove(self.filename)

c=C()
c.remove()

Или вы можете уничтожить обработчик удаления в конце программы:

class C:
    instances = []

    def __init__(self):
        C.instances.append(self)

    def __del__(self):
        C.instances.remove(self)
        os.remove(self.filename)

c = C()
del c

# ... do something ...

for c in C.instances:
    del c.__del__
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...