从多个Python文件中更改相同的文件范围变量
看起来,如果我通过从多个Python文件中更改相同的文件范围变量,python,Python,看起来,如果我通过import语句从多个文件导入同一个Python文件,并更改其中的某个文件范围变量,那么引用更改对其他模块将不可见,而容器更改将不可见 比如说, 第一个示例 first.py import reader import helper reader.change_buf('modified') helper.foo() import reader def foo(): print(reader.BUF) buf = 'original' def change_b
import
语句从多个文件导入同一个Python文件,并更改其中的某个文件范围变量,那么引用更改对其他模块将不可见,而容器更改将不可见
比如说,
第一个示例
first.py
import reader
import helper
reader.change_buf('modified')
helper.foo()
import reader
def foo():
print(reader.BUF)
buf = 'original'
def change_buf(buf):
buf = buf
import reader
import helper
reader.change_first_element('1')
helper.foo()
import reader
def foo():
print(reader.BUF)
buf = ['0', '1', '2']
def change_first_element(new_elem):
buf[0] = new_elem
second.py
import reader
import helper
reader.change_buf('modified')
helper.foo()
import reader
def foo():
print(reader.BUF)
buf = 'original'
def change_buf(buf):
buf = buf
import reader
import helper
reader.change_first_element('1')
helper.foo()
import reader
def foo():
print(reader.BUF)
buf = ['0', '1', '2']
def change_first_element(new_elem):
buf[0] = new_elem
reader.py
import reader
import helper
reader.change_buf('modified')
helper.foo()
import reader
def foo():
print(reader.BUF)
buf = 'original'
def change_buf(buf):
buf = buf
import reader
import helper
reader.change_first_element('1')
helper.foo()
import reader
def foo():
print(reader.BUF)
buf = ['0', '1', '2']
def change_first_element(new_elem):
buf[0] = new_elem
输出
> python first.py
original
> python first.py
['1', '1', '2']
第二个示例
first.py
import reader
import helper
reader.change_buf('modified')
helper.foo()
import reader
def foo():
print(reader.BUF)
buf = 'original'
def change_buf(buf):
buf = buf
import reader
import helper
reader.change_first_element('1')
helper.foo()
import reader
def foo():
print(reader.BUF)
buf = ['0', '1', '2']
def change_first_element(new_elem):
buf[0] = new_elem
second.py
import reader
import helper
reader.change_buf('modified')
helper.foo()
import reader
def foo():
print(reader.BUF)
buf = 'original'
def change_buf(buf):
buf = buf
import reader
import helper
reader.change_first_element('1')
helper.foo()
import reader
def foo():
print(reader.BUF)
buf = ['0', '1', '2']
def change_first_element(new_elem):
buf[0] = new_elem
reader.py
import reader
import helper
reader.change_buf('modified')
helper.foo()
import reader
def foo():
print(reader.BUF)
buf = 'original'
def change_buf(buf):
buf = buf
import reader
import helper
reader.change_first_element('1')
helper.foo()
import reader
def foo():
print(reader.BUF)
buf = ['0', '1', '2']
def change_first_element(new_elem):
buf[0] = new_elem
输出
> python first.py
original
> python first.py
['1', '1', '2']
为什么?tl;dr,因为你用不同的行为做不同的事情。
change_buf
中创建了一个局部变量buf
;在第二个示例中,本地没有这样的变量可访问,因此python将堆栈向上向下搜索适合您的请求的变量,并在模块级范围内找到一个setitem
notation。这两个人的行为是不同的解释(1)中的行为。如果要使用赋值语句显式访问全局变量,请使用 从文档中: 如果没有全局变量,就不可能分配给全局变量,尽管自由变量可能引用全局变量而不声明为全局变量 请注意,第二个示例不是赋值语句;它是对变量
buf
上的\uuuu setitem\uuuu
的方法调用,该变量恰好是类型列表。看起来像这样可能更有意义
foo = [3]
def set_foo():
foo.__setitem__(0,3)
现在您可以看到,foo
是一个被引用的“自由变量”,并且只能以该名称引用全局范围元素。如果对foo
属于哪个范围存在任何歧义,python将无法处理您的情况
Python关于作用域的规则可能有点复杂,因为在第一个示例中,您将全局变量
buf
隐藏在局部变量(函数参数buf
)后面,而在第二个示例中,函数参数(new_elem
)不会冲突。但这还不是全部。在第一个示例中,您在函数中定义了变量buf
,因此它在默认情况下仍然是局部变量-在第二个示例中,您使用它是因为您设置了buf[0]
。您必须将其声明为全局
您应该这样编写reader.py:
buf = 'original'
def change_buf(new_val):
global buf
buf = new_val