3

EDIT: Disclaimer - I don't mean deletion in the sense that applies to languages that aren't memory-managed (e.g. free in C++). Deletion here is to be understood as the fact that the superclass doesn't have the subclass as one of its subclasses anymore after its been deleted.

In Python, you can delete a class (yes I do mean a class, not an instance) by doing the following:

class Super:
    ...
    
class DeleteMe(Super):
    ...

print(Super.__subclasses__())
# [<class '__main__.DeleteMe'>]

del DeleteMe
import gc
gc.collect() # Force a collection

print(Super.__subclasses__())
# []

I am trying to emulate this behaviour but I want the DeleteMe class to be able to destroy itself. Here is what I've tried:

class Super:
    ...
    
class DeleteMe(Super):
    def self_delete(self):
        print(self.__class__)
        # <class '__main__.DeleteMe'>, this looks right
        del self.__class__ # this fails
        import gc
        gc.collect()

print(Super.__subclasses__())
# [<class '__main__.DeleteMe'>]

DeleteMe().self_delete()

It fails with the following traceback:

Traceback (most recent call last):
  File "/Users/rayan/Desktop/test.py", line 10, in <module>
    DeleteMe().self_delete()
  File "/Users/rayan/Desktop/test.py", line 4, in self_delete
    del self.__class__
TypeError: can't delete __class__ attribute

How can I achieve this self-destructing behaviour?

Note: not a duplicate of How to remove classes from __subclasses__?, that question covers the first case where the deletion happens outside of the class

13
  • 1
    "In Python, you can delete a class (yes I do mean a class, not an instance) by doing the following:" No. Python exposes no way to directly delete any object. Python is a memory-managed language. Commented Apr 1, 2022 at 18:24
  • Does this answer your question? Python del on classes Commented Apr 1, 2022 at 18:25
  • 3
    Dare I ask why you are going in this direction? Commented Apr 1, 2022 at 18:25
  • 1
    Fundamentally impossible. If a method of the class is currently executing, there is necessarily a reference to the class in existence, and therefore the class must continue existing. Keep in mind that del doesn't delete things - it's the reduction in reference count that might actually delete something. Commented Apr 1, 2022 at 18:25
  • 1
    You should not be using subclassing for that. That sounds like you need a traditional tree data structure, i.e. a class Tree like you'd have learned about in a Data Structures 101 class. Abusing the class hierarchy to do something like that is a recipe for disaster. Commented Apr 1, 2022 at 18:29

1 Answer 1

7
del DestructMe

This is not deleting the class. This is deleting the name that happens to refer to the class. If there are no other references to the class (and that includes the name you just deleted, any module that's ever imported the class, any instances of the class, and any other places where the class might happen to be stored), then the garbage collector might delete the class when you gc.collect().

Now an instance always knows its own class, via the __class__ attribute. It makes little sense to delete self.__class__, because then what would we be left with? An instance with no class? What can we do with it? We can't call methods on it since those are defined on the class, and we can't do anything object-like on it since it's no longer an instance of object (a superclass of the class we just removed). So really we have a sort of silly looking dictionary that doesn't even do all of the dict things in Python. Hence, disallowed.

You cannot delete data in Python. That's the garbage collector's job. There is no Python equivalent of C's free or C++'s delete. del in Python deletes bindings or dictionary entries. It does not remove data; it removes pointers that happen to point to data.

Sign up to request clarification or add additional context in comments.

1 Comment

" then the garbage collector might delete the class when you gc.collect()." so, important to note, gc only controls the auxilliary garbage collector. Classes are often invovled in reference cycles (to themselves!) but if a reference count reaches 0, the object is immediately reclaimed regardless of what gc is doing

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.