Временные ссылки автоматически очищаются в Python?

Это в основном вопрос о времени жизни временных. Если функция возвращает объект, но ссылка не назначена переменной и используется только для вызова метода в возвращенном объекте, автоматически очищается временная ссылка?

Чтобы привести конкретный пример, предположим, что есть цепочка вызовов методов:

o.method_a().method_b()

Временная ссылка возвращена o.method_a() автоматически очищается при вызове method_b() заканчивается, как если бы строка была написана так:

tmp = o.method_a()
try:
    tmp.method_b()
finally:
    tmp = None

РЕДАКТИРОВАТЬ: меня интересует общий ответ. CPython завершает объекты, как только число ссылок падает до 0. Другие реализации Python могут не завершать объекты сразу. Мне интересно, похож ли язык Python на C++, который гарантирует, что временные объекты уничтожаются в конце оператора, для которого они были созданы. (За исключением того, что в Python вопрос заключается в том, очищаются ли временные ссылки в конце оператора, для которого они были созданы.)

В C++ подобный код может быть реализован с помощью:

class B {
public:
    void method_b();
};

class A {
public:
    std::shared_ptr<B> method_a();
};



A o;
o.method_a()->method_b();

Стандарт C++ гласит: "Временные объекты уничтожаются как последний шаг в оценке полного выражения... который (лексически) содержит точку, в которой они были созданы. Это верно, даже если эта оценка заканчивается созданием исключения". В этом примере это означает, что временный std::shared_ptr<B> объект, созданный при вызове A::method_a() уничтожается сразу по окончании оценки полного выражения o.method_a()->method_b();, Уничтожение std::shared_ptr означает очистку ссылки на общий объект.

3 ответа

Решение

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

>>> class C(object):
...     def foo(self):
...          return B()
... 
>>> class B(object):
...     def __del__(self):
...         print 'deleting %r' %self
...     def bar(self):
...         print 'I am method bar of %r' %self
... 
>>> c = C()
>>> c.foo().bar()
I am method bar of <__main__.B object at 0xa187d2c>
deleting <__main__.B object at 0xa187d2c>

В качестве примечания: если есть ссылка на временный объект из какого-либо другого объекта, он не будет удален. Объект является мусором, только когда счетчик ссылок равен нулю.

Также заметка о del, del просто сбрасывает счетчик ссылок на объект. Это не удаляет объект. Например, если a = b = C(), del a удаляет только имя a и сбрасывает счетчик ссылок для объекта C(), но на самом деле не удаляет его, потому что b до сих пор относится к этому.

Вы правы, подсчет ссылок является реализацией CPython. Что касается других реализаций, спецификация Python не дает никаких гарантий относительно того, когда объекты уничтожаются.

Вот что говорит Python Language Reference по этому вопросу:

Объекты никогда не уничтожаются явно; однако, когда они становятся недоступными, они могут быть собраны мусором. Реализация может откладывать сборку мусора или вообще ее пропускать - вопрос качества реализации в том, как реализована сборка мусора, до тех пор, пока не будут собраны объекты, которые все еще доступны.

Что вы подразумеваете под "очищенным"? Вы могли бы иметь в виду очищенный, как в "деструкторе __del__называется "или очищается, как в" связанная память освобождается ". Это не гарантировано. Например, вы можете сравнить CPython 2.7.2 с PyPy 1.7.0 [на примере @Praveen Gollakota]:

class C(object):
     def foo(self):
         return B()

class B(object):
    def __del__(self):
        print 'deleting %r' %self
    def bar(self):
        print 'I am method bar of %r' %self

c = C()
c.foo().bar()

print 'END OF LINE'

производит

localhost-2:coding $ python tempref.py
I am method bar of <__main__.B object at 0x1004b7d90>
deleting <__main__.B object at 0x1004b7d90>
END OF LINE
localhost-2:coding $ pypy tempref.py
I am method bar of <__main__.B object at 0x0000000102bc4cb0>
END OF LINE

Хороший вопрос.

Я предполагаю, что объект добавлен в сборщик мусора python из python, потому что у объекта нет ссылки. Затем это немедленно удаляется.

Другие вопросы по тегам