Reputation: 1673
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
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
Reputation: 180482
You can use gc.collect after deleting:
del A
from gc import collect
collect()
print( object.__subclasses__())
Upvotes: 1