del
удаляет эту переменную, а не базовый объект.Этот объект удаляется, когда его счетчик ссылок падает до 0, и сборщик мусора решает удалить его.
Представьте, что у каждого объекта есть счетчик.Допустим, ваши машины являются list
объектами (только для простоты. Концепция одинакова для каждого изменяемого объекта):
car1 = [1, 2, 3]
Здесь счетчик для объекта car1
указывает на 1.Каждый раз, когда что-то указывает на этот объект, счетчик увеличивается:
car2 = car1
car3 = car1
Теперь счетчик равен 3. Когда вы удаляете переменную, используя del
, ссылка понижается, но объект удаляется только тогда, когдазначение счетчика падает до 0, и сборщик мусора решает удалить этот объект:
del car2
Счетчик равен 2, и car1
и car3
все еще указывают на него, попытка изменить car1
приведет к изменениюcar3
:
car1.append(4)
print(car3) # output: [1, 2, 3, 4]
Вывод: когда существует несколько ссылок на изменяемый объект, все они могут изменить этот объект, но ни один из них не может удалить объект самостоятельно.Когда вы собираете эти автомобили в список, у вас все еще есть ссылка на эти автомобили:
car4 = ["Toyota"]
car5 = ["Audi"]
car6 = ["Tesla"]
c = [car4, car5, car6]
my_cars = []
for x in c:
my_cars.append(x)
Здесь c
и my_cars
оба содержат ссылки на одни и те же автомобили.Каждый из них указывает на отдельный объект list
, а каждый объект list
указывает на каждый объект car
от своего имени.Каждый увеличивает счетчик на единицу, таким образом, счетчик увеличивается на 2. Вы можете изменить автомобили, используя любой из списков:
c[0][0] = "Mercedes-Benz"
print(my_cars[0]) # output: ['Mercedes-Benz']
Но, как мы пришли к выводу выше, вы не можете уничтожить объект, используя только одну изссылки:
del c[0]
print(my_cars) # output is still [['Mercedes-Benz'], ['Audi'], ['Tesla']]. The object still exists.
С другой стороны, когда вы просите c
и my_cars
указать один и тот же список, они оба указывают на этот (один) list
объект.Обратите внимание, что существует только один list
объект, и любые изменения в этом объекте влияют на обе переменные :
c = [car4, car5, car6]
my_cars = c
del c[0]
print(my_cars) # output: [['Mercedes-Benz'], ['Tesla']]. The first object is removed.
Обратите внимание, что тогда объект все равно не может быть удален, если какой-либо другойпеременные все еще указывают на него:
print(car4) # output: ['Mercedes-Benz']. car4 is still pointing to that car object, thus it is not destroyed.
Но один объект list
, на который указывают c
и my_cars
, больше его не содержит.