1

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?

Jeonous
  • 23
  • 4
  • What is it you are trying to accomplish? Save the instance of the Staff object in a list then when the instance is deleted remove it from the list? – Daniel Butler May 27 '21 at 02:02
  • @DanielButler Thank you for answering! Yes, right. 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. – Jeonous May 27 '21 at 02:05

1 Answers1

0

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!

Kraigolas
  • 5,121
  • 3
  • 12
  • 37
  • Thank you for answering! I understood that your method works well. but the finalizer method (__del__()) must be used... – Jeonous May 27 '21 at 02:22
  • @JEONOUS See my edit, as it may be more of use to you – Kraigolas May 27 '21 at 02:28
  • Thank you for answering again. but I have a question. In python, I can check the instance that exists in the static list, but why do I can't remove it with remove()? – Jeonous May 27 '21 at 04:19
  • Your answer is perfect and I understood it. In fact, though the reason is not written here, I should delete the instance of the static list inside of __del__(). – Jeonous May 27 '21 at 04:21
  • @JEONOUS As one final note, when you override `__del__()` you are defining `del`. You should be using `del`. Just as you write `len(Staff.staffs)` instead of `Staff.staffs.__len__()` – Kraigolas May 27 '21 at 16:07