是__subclasses __()缓存了吗?

时间:2015-08-04 17:12:56

标签: python inheritance sys

我在三个不同的文件中有三个模型。 这些模块都在sys.path

a.py:
class A(object):
    pass

b.py:
class B(A):
    passs

c.py:
class C(A):
    pass

现在我想得到A:

的子类
print A.__subclasses__()
>> [<class 'b.B'>, <class 'c.C'>]

到目前为止一切顺利。 但是现在我从sys.path中删除c.py并再次获取子类。我会除外,只剩下B。 但输出结果是一样的:

# remove c.py from sys.pyth
sys.path.remove('../c')
print A.__subclasses__()
>> [<class 'b.B'>, <class 'c.C'>]

所以以某种方式缓存__subclasses__调用。 是否可以强制__subclasses__再次搜索sys.path?

2 个答案:

答案 0 :(得分:3)

不,class.__subclasses__()没有缓存,不是真的;内部实现使用弱引用。但模块是;删除c.py文件不会卸载模块。

您还必须删除该模块:

import sys

del sys.modules['c']

并确保没有其他模块参考。

因为类本身涉及很多引用(它们指向它们的基类,对于初学者),你需要确保运行gc.collect()以确保已删除的类对象不再保留在内存中:

>>> 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__()
[]

答案 1 :(得分:0)

您的示例不完整,不幸的是,您遗漏的部分是最重要的。让我纠正你的例子:

<强> a.py:

class A(object):
    pass

<强> b.py:

from a import A    # you left this out
class B(A):
    passs

<强> c.py:

from a import A    # you left this out
class C(A):
    pass

一旦你import一个模块,它仍然被导入,除非你明确地卸载它。修改sys.path不会影响已加载模块的集合。