I have three models in three different files.
The modules are all in sys.path
a.py:
class A(object):
pass
b.py:
class B(A):
passs
c.py:
class C(A):
pass
Now I want to get the subclasses of A:
print A.__subclasses__()
>> [<class 'b.B'>, <class 'c.C'>]
So far so good.
But now I remove c.py from my sys.path and get the subclasses again. I would except, that there will be only B left.
But the output is the same:
# remove c.py from sys.pyth
sys.path.remove('../c')
print A.__subclasses__()
>> [<class 'b.B'>, <class 'c.C'>]
So somehow the __subclasses__ call is cached.
Is it possible to force __subclasses__ to search sys.path again?
No, class.__subclasses__() is not cached, not really; the internal implementation uses weak references. But modules are; removing the c.py file will not unload the module.
You'd have to delete the module too:
import sys
del sys.modules['c']
and make sure to have no other references to the module.
Because classes involve a lot of references themselves (they point to their base classes, for starters) you need to make sure you run gc.collect() to make sure the deleted class objects are no longer retained in memory:
>>> class B(A): pass
...
>>> A.__subclasses__()
[<class '__main__.B'>]
>>> del B
>>> A.__subclasses__()
[<class '__main__.B'>]
>>> gc.collect(0)
0
>>> gc.collect(1)
3
>>> gc.collect(1)
0
>>> gc.collect(2)
0
>>> A.__subclasses__()
[]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With