wolverdude
wolverdude

Reputation: 1673

Is it possible to delete (not just unlink) a class?

Suppose I define a class.

>>> class A(object):
>>>     pass

Then I want to delete that class. I can use del to unlink it from the variable A.

>>> del A
>>> A
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'A' is not defined

But del does not actually remove the class itself. I can tell this because it's still listed among object's subclasses.

>>> object.__subclasses__()
[..., <class '__main__.A'>]

Not that I think this will work, but...

>>> del object.__subclasses__()[-1]
>>> object.__subclasses__()
[..., <class '__main__.A'>]

Is there a way to actually remove the class so that it is no longer in object.__subclasses__()?

Upvotes: 3

Views: 351

Answers (2)

chown
chown

Reputation: 52778

Weak references to A will stick around after you del A. One reason this is necessary is to allow cyclic references without preventing garbage collection. Try this to see what is still referencing it (this is specific to the python interpreter, may vary if you run as a script file):

>>> class A(object):
...     pass
...
>>> A
<class '__main__.A'>
>>> del A
>>> A
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'A' is not defined

>>> object.__subclasses__()[-2]
<class '__main__.A'>

>>> # using weakref
>>> import weakref
>>> weakref.getweakrefs(object.__subclasses__()[-2])
[<weakref at 0x800fa4ba8; to 'type' at 0x800f9d420 (A)>]

>>> # Another method using gc to see the referrers:
>>> import gc
>>> gc.collect()
>>> gc.get_referrers(object.__subclasses__()[-2])
[<__main__.A object at 0x800face90>, (<class '__main__.A'>, <type 'object'>), <attribute '__dict__' of 'A' objects>, <attribute '__weakref__' of 'A' objects>]

>>> # See the referents
>>> print '\n'.join(map(str, gc.get_referents(object.__subclasses__()[-2])))
{'__dict__': <attribute '__dict__' of 'A' objects>, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None}
(<class '__main__.A'>, <type 'object'>)
(<type 'object'>,)
<type 'object'>

More reading on the subject:

http://pymotw.com/2/weakref/
https://docs.python.org/2/library/gc.html
https://docs.python.org/2.7/library/weakref.html
https://www.python.org/dev/peps/pep-0205/
https://docs.python.org/release/2.6.4/library/stdtypes.html#class.subclasses

Upvotes: 3

Padraic Cunningham
Padraic Cunningham

Reputation: 180482

You can use gc.collect after deleting:

del A
from gc import collect
collect()
print( object.__subclasses__()) 

Upvotes: 1

Related Questions