Уничтожение генератора при возникновении оператора останова - PullRequest
3 голосов
/ 27 января 2012

Я хочу знать, когда метод Obj. del () будет называться.

def my_integers():
    Obj = ExitObj()
    i = 0
    while(1):
        yield i
        i += 1
def test_fun():
    for i in my_integers():
        if i > 3:
            break 
anything_function()
test_fun()

Я выполнил тест, и Obj, казалось, был удален сразу после оператора break: до того, как что-нибудь в функции () вышло из цикла.

Могу ли я рассчитывать на это и дать некоторые задачи, которые я хочу выполнить, когда цикл передается методу __ del__ объекта, определенного внутри генератора?

Ответы [ 3 ]

9 голосов
/ 27 января 2012

Я хочу знать, когда будет вызван метод Obj.__del__().

Вы не можете.Возможно, никогда.Финализаторы в Python (или в любой среде с автоматической схемой сборки мусора, на самом деле) не гарантированно работают вообще, и их следует использовать только для последней очистки.Если вы хотите предсказуемое управление временем жизни, используйте with оператор и контекстные менеджеры .

class Foo(object):
    def __enter__(self):
        print 'Entered with block'
    def __exit__(self, *exc_info):
        print 'Exited with block'
        return False

with Foo():
    pass
2 голосов
/ 27 января 2012

Как правило, вы не можете полагаться на порядок вызова деструктора.Деструкторы вызываются, когда сборщик мусора восстанавливает объект.Это может произойти в неопределенном будущем или не произойдет вообще, если ваша программа умирает по исключению.

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

0 голосов
/ 27 января 2012

Вот что говорит Python Language о object.__del__(self),

x.__del__() - ... вызывается только тогда, когда счетчик ссылок x‘ достигает нуля. Некоторые распространенные ситуации, которые могут помешать обнулению счетчика ссылок объекта, включают: циклические ссылки между объектами; ссылка на объект в кадре стека функции, которая перехватила исключение ...

Так что вам не следует полагаться на __del__ для очистки. Менеджер контекста (как Cat Plus Plus упоминает выше ), является правильным выбором.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...