【问题标题】:Scope of Python Class Variable?Python类变量的范围?
【发布时间】:2014-04-18 11:44:16
【问题描述】:

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

考虑这个例子,在 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 之间没有重置或删除类变量?

【问题讨论】:

  • @mgilson 我在问为什么变量不是在两个调用之间被垃圾收集;该链接似乎在谈论实例和类变量之间的区别。

标签: python class scope


【解决方案1】:

这是一个类属性。在您的情况下,字典绑定到 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 中挑选出正确的项目并为您提供对它的引用。这有几个原因。

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

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

# mod.py
CONSTANT = object()

现在您想在foo.pybar.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 可能foobar 中是不同的,这将是非常令人惊讶的。

【讨论】:

  • 谢谢。我担心它会被垃圾收集,因为没有明确的参考。 bar的全局命名空间什么时候会被删除?在python关闭过程中?
  • @E.Beach -- 啊,我现在明白你的问题(以及函数本地导入的原因)。我已经编辑了
猜你喜欢
  • 2011-08-24
  • 2022-01-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多