My purpose is as below: If a new instance created, the instance must be added to the static list. and when a created instance is deleted, it must be deleted from the static list
And finalizer method, 'del()' must be used.
The python code I had trouble with is as below:
class Staff:
staffs = [] # static customer list
def __init__(self, name):
self.name = name
print("A staff is created!")
def __del__(self):
Staff.staffs.remove(self)
print("A staff is deleted!")
if __name__ == '__main__':
# create a staff
Staff.staffs.append(Staff("Harry"))
# delete a staff
Staff.staffs[0].__del__()
And the error is as below:
Exception ignored in: <function Staff.del at 0x0000028A3675EF70>
Traceback (most recent call last): File "(Path)\temp.py", line 11, in del Staff.staffs.remove(self)
ValueError: list.remove(x): x not in list
And I can check that the created instance exists in the static list like below code
def check(self):
print("Length of Static List:", len(Staff.staffs))
print("self", self)
for a_staff in Staff.staffs:
if a_staff == self:
print("a_staff", a_staff)
print()
Result:
Length of Static List: 1
self <main.Staff object at 0x000001FF7506CFD0>
a_staff <main.Staff object at 0x000001FF7506CFD0>
The memory addresses of the instances are totally the same but I don't know why the interpreter says that there is no instance in the static list.
When I ran similar code in Java there was no problem.
Why does the error occur?
Note that
class Staff:
staffs = [] # static customer list
def __init__(self, name):
self.name = name
print("A staff is created!")
def delete(self):
Staff.staffs.remove(self)
print("A staff is deleted!")
if __name__ == '__main__':
# create a staff
Staff.staffs.append(Staff("Harry"))
# delete a staff
Staff.staffs[0].delete()
works fine. All I have done is renamed __del__
to delete. You can try to interpret the documentation on it which notes that
Due to the precarious circumstances under which del() methods are invoked, exceptions that occur during their execution are ignored, and a warning is printed to sys.stderr instead.
The above quote explains your error. However, as other posts outline, __del__
is a
really low-level method which you don't need 99.9% of the time
so it should be sufficient to just use the code above, which marks your instance for garbage collection.
If you must add additional content to the __del__
command, try this:
class Staff:
staffs = [] # static customer list
def __init__(self, name):
self.name = name
print("A staff is created!")
def __del__(self):
print("A staff is deleted!")
if __name__ == '__main__':
# create a staff
Staff.staffs.append(Staff("Harry"))
print(f"The length of Staff before delete is: {len(Staff.staffs)}")
# delete a staff
del Staff.staffs[0]
print(f"The length of Staff after delete is: {len(Staff.staffs)}")
This outputs:
A staff is created!
The length of Staff before delete is: 1
A staff is deleted!
The length of Staff after delete is: 0
So the item is deleted, and your text is printed, with no exception!