__subclasses__() 是否被缓存?
Is __subclasses__() cached?
我在三个不同的文件中有三个模型。
模块都在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?
不,class.__subclasses__()
没有缓存,不是真的;内部实现使用弱引用。但是 modules 是;删除 c.py
文件不会卸载模块。
您也必须删除该模块:
import sys
del sys.modules['c']
并确保没有对该模块的其他引用。
因为 classes 本身涉及很多引用(他们指向他们的基础 classes,首先)你需要确保你 运行 gc.collect()
确保已删除的 class 个对象不再保留在内存中:
>>> 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__()
[]
您的示例不完整,不幸的是,您遗漏的部分是最重要的。让我纠正你的例子:
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
不会影响加载模块集。
我在三个不同的文件中有三个模型。
模块都在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?
不,class.__subclasses__()
没有缓存,不是真的;内部实现使用弱引用。但是 modules 是;删除 c.py
文件不会卸载模块。
您也必须删除该模块:
import sys
del sys.modules['c']
并确保没有对该模块的其他引用。
因为 classes 本身涉及很多引用(他们指向他们的基础 classes,首先)你需要确保你 运行 gc.collect()
确保已删除的 class 个对象不再保留在内存中:
>>> 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__()
[]
您的示例不完整,不幸的是,您遗漏的部分是最重要的。让我纠正你的例子:
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
不会影响加载模块集。