从多个Python文件中更改相同的文件范围变量

时间:2016-04-25 13:37:24

标签: python

似乎如果我通过几个文件中的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']

为什么?

2 个答案:

答案 0 :(得分:0)

tl; dr因为你用不同的行为做了不同的事情。

  1. 在第一个示例中,您在函数buf中创建了一个局部变量change_buf;在第二个例子中,没有这样的变量可以在本地访问,因此python向下移动堆栈以查找适合您请求的变量,并在模块级范围内找到一个变量。
  2. 您的第一个示例使用赋值语句,您的第二个语句是花哨的setitem表示法。两者的行为不同。
  3. 解释(1)中的行为,This question is similar。如果要使用赋值语句显式访问全局变量,请使用global or nonlocal keywordas 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