Сборка мусора объекта после исключения - PullRequest
1 голос
/ 19 февраля 2010

Я заметил, что после исключения у меня есть объект, для которого конструктор не вызывается, что приводит к удержанию блокировки.Как лучше всего улучшить ситуацию?Будет ли решение del в блоке исключений быть решением?

b=BigHash(DB_DIR, url)
meta = bdecode(b.get())
return meta

b содержит блокировку, которая освобождается при уничтожении (это объект C ++), b.get () создает исключение.

Ответы [ 3 ]

3 голосов
/ 19 февраля 2010

Независимо от того, что вы хотите, чтобы блокировка была снята - независимо от того, было ли выброшено исключение. В этом случае, вероятно, лучше снять блокировку / удаление b в предложении finally::

b=BigHash(DB_DIR, url)
try:
    meta = bdecode(b.get())
finally:
    del b # or whatever you need to do to release the lock
return meta

Вы также можете использовать менеджер контекста - http://docs.python.org/library/stdtypes.html#typecontextmanager. Просто добавьте код для освобождения блокировки в функции BigHash.__exit__, которая будет вызываться после выхода из блока with в следующем коде:

with BigHash(DB_DIR, url) as b:
    meta = bdecode(b.get())
return meta
1 голос
/ 19 февраля 2010

Вам нужно сделать что-то подобное, чтобы убедиться, что b разблокировано

b=BigHash(DB_DIR, url)
try:
    meta = bdecode(b.get())
    return meta
finally:
    #unlock b here

Более понятный способ, если BigHash может работать как контекст, поэтому вы можете написать

with b as BigHash(DB_DIR, url):
    meta = bdecode(b.get())
    return meta

Возможно, вам придется добавить код в BigHash, чтобы он работал как контекст

0 голосов
/ 19 февраля 2010

Вызов del по имени - это то, что вы никогда не должны делать. Вызов del не гарантирует ничего полезного о том, что произойдет с базовым объектом. Вы никогда не должны зависеть от метода __del__ в том, что вам нужно.

del избавляется только от одной ссылки на объект, что может сбивать с толку, когда вы, возможно, сделали больше, не задумываясь. Следовательно, del полезен для очистки пространства имен, а не для управления временем жизни объектов, а это даже не здорово для этого - правильный способ управлять временем жизни имени - поместить его в функцию и сделайте так, чтобы он вышел из области видимости или поместите его в блок with.

Вам необходимо оснастить BigHash возможностью явного снятия блокировки , методом release, unlock или close. Если вы хотите использовать это с менеджером контекста (with), вы можете определить __exit__, который будет вызываться в предсказуемое и полезное время.

...