简体   繁体   中英

Last object in a list isn't deleted after deleting it. When is it effectively deleted?

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?

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)]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM