似乎如果我通过几个文件中的import
语句导入相同的Python文件并更改其中的一些文件范围变量,那么当容器更改时,参考更改将对其他模块不可见。< / p>
例如,
第一个例子
first.py
import reader
import helper
reader.change_buf('modified')
helper.foo()
second.py
import reader
def foo():
print(reader.BUF)
reader.py
buf = 'original'
def change_buf(buf):
buf = buf
输出
> python first.py
original
第二个例子
first.py
import reader
import helper
reader.change_first_element('1')
helper.foo()
second.py
import reader
def foo():
print(reader.BUF)
reader.py
buf = ['0', '1', '2']
def change_first_element(new_elem):
buf[0] = new_elem
输出
> python first.py
['1', '1', '2']
为什么?
答案 0 :(得分:0)
tl; dr因为你用不同的行为做了不同的事情。
buf
中创建了一个局部变量change_buf
;在第二个例子中,没有这样的变量可以在本地访问,因此python向下移动堆栈以查找适合您请求的变量,并在模块级范围内找到一个变量。setitem
表示法。两者的行为不同。解释(1)中的行为,This question is similar。如果要使用赋值语句显式访问全局变量,请使用global
or nonlocal
keyword,as is done here
来自文档:
在没有全局变量的情况下分配给全局变量是不可能的,尽管自由变量可以引用全局变量而不被声明为全局变量。
请注意,您的第二个示例不是赋值语句;它是对变量__setitem__
的{{1}}方法调用,恰好是类型列表。看起来像这样可能更有意义
buf
现在您看到foo = [3]
def set_foo():
foo.__setitem__(0,3)
是一个被引用的“自由变量”,仅可以通过该名称引用全局范围元素。如果foo
所属的范围有任何歧义,python将无法处理您的案例。
Python关于作用域的规则可能有点复杂,but are unambiguous
答案 1 :(得分:0)
仅仅因为在第一个示例中,您将全局变量buf
隐藏在本地变量(函数参数buf
)后面,而在第二个示例中,函数参数(new_elem
)不会碰撞。但那还不是全部。在第一个示例中,您在函数中定义变量buf
,因此默认情况下它仍然是本地的 - 在第二个示例中,您使用它,因为您设置了{ {1}}。您必须声明buf[0]
你应该这样写一下reader.py:
global