Python: что происходит с неназванными объектами?

#python #memory

#python #память

Вопрос:

Пример:

 class A:
  def __init__(self, val):
    self.val = val

a1 = A(1)
a2 = A(2)
a20 = A(20)

dct = {a1 : A(10), a2: a20}

del dct[a1] # what happens to the unnamed `A(10)`?
 

Поскольку ничто не указывает или не ссылается на «неназванный» A(10) , что с ним происходит?

Немного более надуманный случай:

 dct = {"key": ("first", [2])}

l = dct["key"][1] # points to the `[2]` list

del dct["key"]
 

В этом случае

  1. ("first", [2]) Кортеж не имеет имени.
  2. [2] Список именован l .

Когда мы del dct["key"] , что происходит с кортежем? Я знаю, что список l сохраняется, поскольку на него все еще есть ссылка.

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

1. В конечном итоге они собираются как мусор (хотя в качестве детали реализации строки в исходном коде модуля интернируются, поэтому "first" строка в кортеже фактически сохраняется).

Ответ №1:

Вы можете проверить это сами, реализовав метод del . Это позволит вам увидеть, когда сборщик мусора удаляет экземпляры объектов из памяти:

 class A:
  def __init__(self, val):
    self.val = val

  def __del__(self):
      print("object",self.val,"deleted")


a1 = A(1)
a2 = A(2)
a20 = A(20)

dct = {a1 : A(10), a2: a20}

print("deleting key a1...")
del dct[a1] # what happens to the unnamed `A(10)`?

print("deleting dct (no instance is deleted because of variables references)")
dct = 0

print("clearing variables")
a1 = a2 = a20 = 0
 

вывод:

 deleting key a1...
object 10 deleted
deleting dct (no instance is deleted because of variables references)
clearing variables
object 1 deleted
object 2 deleted
object 20 deleted
 

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

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

1. Спасибо! Можете ли вы уточнить, что означает «(ни один экземпляр не удаляется из-за ссылок на переменные)»? Что я понял, так это: 1. Перед выполнением dct = 0 у нас есть: dct == {a2: a20} . 2. После выполнения dct = 0 у нас нет способа ссылаться на {a2: a20 , но вы также говорите, что {a2: a20} само по себе все еще плавает, потому a2 a20 что ссылка на переменную and все еще существует? Спасибо!

2. Да, до тех пор, пока существует хотя бы одна ссылка на любую переменную (напрямую, как in a20 или косвенно, как in dct ), экземпляр объекта остается «живым». Когда все ссылки исчезают, объект автоматически удаляется из памяти. В этом случае переменная a20 все еще ссылается на экземпляр A(20) после очистки dct , поэтому A(20) объект остается активным до a20 тех пор, пока сама переменная не будет очищена.

Ответ №2:

Для второго примера мы можем визуализировать это следующим образом:

введите описание изображения здесь

Вы можете сами визуализировать свой первый пример здесь.