Reputation: 23
The following code should delete each of the n
Human objects, then print the last line, but it deletes only 4 of them, the 5th gets deleted (I think) after execution stops.
class Human():
def __init__(self, name):
self.name = name
def __del__(self):
print(f'{self.name} is dead')
n = 5
humans = []
for i in range(n):
human = Human('Bob')
humans.append(human)
for i in reversed(range(n)):
del humans[i]
print('DEATH')
The output is the following (Powershell and Python 3.8.1):
Bob is dead
Bob is dead
Bob is dead
Bob is dead
DEATH
Bob is dead
After the 2nd for-loop humans
is empty, so it's not possible to delete the last item by del humans[0]
. Other ways of deleting contents (del humans[:]
or humans.clear
) of the list also don't fix the issue, the output stays the same.
So, is this how the code should behave or is there some issue?
Upvotes: 2
Views: 220
Reputation: 71522
One of the objects isn't being garbage-collected because there's still a reference to it:
class Human():
def __init__(self, name):
self.name = name
def __del__(self):
print(f'{self.name} is dead')
n = 5
humans = []
for i in range(n):
human = Human(f'Bob {i}')
humans.append(human)
for i in reversed(range(n)):
print(f'Die, {humans[i].name}!')
del humans[i]
print('DEATH')
print(f"(except for {human.name} whom we haven't forgotten about!)")
If you want to avoid that dangling reference, an easy fix is not to create it in the first place:
n = 5
humans = []
for i in range(n):
humans.append(Human(f'Bob {i}'))
or better yet:
n = 5
humans = [Human(f'Bob {i}') for i in range(n)]
Upvotes: 8