在Python中访问全局变量时的导入行为

时间:2014-02-16 17:45:06

标签: python python-2.7 python-import

bar.py

var = 1
def set_var():
    global var
    var = 2

foo.py

from bar import *

print(var)
set_var()
print(var)

foo2.py

import bar

print(bar.var)
bar.set_var()
print(bar.var)

如果我运行foo.py,则输出为:

1
1

但如果我运行foo2.py,则输出为:

1
2

这就是我所期望的。

我只想了解这种行为,因为我是Python的新手并且没有找到合理的理由。

PD:附加信息。我想开发一个使用单例对象的模块,并且我有一些使用该对象的遗留代码。我宁愿不在遗留代码中为该对象的每个引用添加前缀,这就是为什么我使用 from library import object 语法导入模块会有所帮助。

因此在库中我有访问全局对象的函数来配置它,就像在示例中一样(bar.py)。在遗留代码中,我希望只需要在foo.py中进行某种导入。

感谢您的指导。

编辑:第二个例子

在bar.py

var_list = list(range(0, 2))
var_list2 = list(range(0, 2))

def set_var():
    global var_list
    var_list = list(range(0, 3))
    var_list2.append(2)

在foo.py

from bar import *

print(var_list)
print(var_list2)
set_var()
print(var_list)
print(var_list2) 

输出结果为:

[0, 1]
[0, 1]
[0, 1]
[0, 1, 2]

我理解在 set_var 中我们正在使用 list()创建一个新对象,但我希望foo.py可以在我引用时访问这个新对象它使用 var_list (就像使用语法 bar.var_list 一样)。我需要更多背景知识。

由于

2 个答案:

答案 0 :(得分:1)

bar.py中的

“var”为bar.var。总是(除非是__main__.var,但这是一个不同的问题)。对该名称的任何操作仅发生在该模块中,而不是发生在通过from bar import ...完成的任何其他地方的副本。

答案 1 :(得分:1)

此行为有两个组成部分:

  1. 正如@Ignacio已经解释的那样,所谓的"全局"在python中实际上有模块范围的范围。

  2. python中的变量名指向一个对象(可变或不可变,类或整数,它们都是相同的)。当您分配给现有名称时,您将断开与之前指向的任何名称的关联。

  3. 这就是foo所做的:

    # import
    foo.var = bar.var
    foo.set_var = bar.set_var
    
    print(foo.var)
    foo.set_var()   # sets bar.var
    print(foo.var)
    
    当然,

    foo2设置并打印bar.var

    关于第二个示例:您可以修改列表,而不会破坏与指向它的变量的关联。因此,对var_list2的更改随处可见(请注意,您永远不会分配给它)。但是,由于您分配给var_list,因此在第一个示例中它的行为类似于var