Python类变量的范围?

时间:2014-03-13 15:43:31

标签: python class scope

类变量本质上是全局变量吗?

在bar.py中考虑这个例子:

class Bar(object):
    b = {}

然后在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之间没有重置或删除类变量?

1 个答案:

答案 0 :(得分:3)

这是一个类属性。在您的情况下,dict绑定到类Bar。每次导入bar时,都会获得相同的类bar.Bar(毕竟,它位于bar的全局命名空间中),因此,您获得相同的字典{{1} }。

如果您希望每个bar.Bar.b实例具有不同的dict,则需要创建一个实例:

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() 没有被垃圾收集,当你导入东西时,python存储对该模块的引用(参见sys.modules)。下次导入该模块时,python会从bar中选择正确的项目,并为您提供参考。这有几个原因。

  • 效率 - 为什么要重新评估您已经评估过的代码?
  • Sane行为

想象一个具有特殊值的模块:

sys.modules

现在您想在# 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.CONSTANTfoo中会有所不同,这会非常令人惊讶。