类变量本质上是全局变量吗?
考虑这个例子,在bar.py中:
class Bar(object):
b = {}
then in foo.py:
def foo1():
import bar
bar.Bar.b["key"] = "foo1"
def foo2():
import bar
print bar.Bar.b.get("key", "foo2")
foo1()
foo2()
"key"值始终为"foo1"。
对于我的目的,这似乎是一个全局变量。但是为什么在调用foo1和foo2之间不重置或删除类变量呢?
这是一个类属性。在您的示例中,字典绑定到类Bar
。每次导入bar
时,您都会获得相同的类bar.Bar
(毕竟,它位于bar
的全局命名空间中),因此,您将获得相同的字典bar.Bar.b
。
如果你想让每个Bar
实例有一个不同的字典,你需要创建一个实例:
class Bar(object):
def __init__(self):
self.b = {}
然后:
def foo1():
import bar
bar.Bar().b["key"] = "foo1"
def foo2():
import bar
print bar.Bar().b.get("key", "foo2")
foo1()
foo2()
至于为什么模块bar
没有被垃圾收集,当你导入一些东西时,python存储对该模块的引用(参见sys.modules
)。下次导入该模块时,python将从sys.modules
中挑选出适当的项,并为您提供对它的引用。这有几个原因。
- 效率——为什么要重新评估已经评估过的代码? <
- 理智的行为/gh>
想象一个具有特殊值的模块:
# mod.py
CONSTANT = object()
现在你想在foo.py
和bar.py
中使用它。
# bar.py
import mod
def bar():
return mod.CONSTANT
# foo.py
import mod
import bar
if bar.bar() is mod.CONSTANT:
do_something()
如果导入没有缓存,那么mod.CONSTANT
在foo
和bar
中可能是不同的,这将是非常令人惊讶的。