带进口的全局变量

时间:2011-01-16 17:30:33

标签: python global

first.py

myGlobal = "hello"

def changeGlobal():
   myGlobal="bye"

second.py

from first import *

changeGlobal()
print myGlobal

我得到的输出是

  

您好

虽然我认为应该是

  

再见

为什么在调用myGlobal函数后全局变量changeGlobal()没有变化?

3 个答案:

答案 0 :(得分:18)

尝试:

def changeGlobal():
    global myGlobal
    myGlobal = "bye"

实际上,这也不起作用。当你import *时,你创建一个新的本地模块全局myGlobal,它不受你想要的改变的影响(只要你不改变变量,见下文) 。您可以改为使用它:

import nice

nice.changeGlobal()
print nice.myGlobal

或者:

myGlobal = "hello"

def changeGlobal():
   global myGlobal
   myGlobal="bye"

changeGlobal()

但是,如果您的global是一个可变容器,那么您现在正在持有对mutable的引用,并且能够看到对它进行的更改:

myGlobal = ["hello"]

def changeGlobal():
    myGlobal[0] = "bye"

答案 1 :(得分:6)

我曾经和你一样关心过,从 Norman Matloff Quick and Painless Python Tutorial阅读以下部分真的是一个很好的帮助。以下是您需要了解的内容(从Matloff的书中复制):

Python并不真正允许C / C ++这样的全局变量。导入的Python模块不能直接访问导入它的模块中的全局变量,反之亦然。

例如,请考虑这两个文件 x.py

# x.py
import y
def f():
  global x
  x = 6
def main():
  global x
  x = 3
f()
y.g()
if __name__ == ’__main__’:
  main()

y.py

# y.py
def g():
  global x
  x += 1

x.py 中的变量x在整个模块 x.py 中可见,但在 y.py 中则不可见。实际上,执行该行 x + = 1

后者中的

将导致出现错误消息,“未定义全局名称'x'。”

实际上,模块中的全局变量仅仅是该模块的属性(即成员实体),类似于类变量在类中的角色。当模块 B 由模块 A 导入时, B 的命名空间将复制到 A 。如果模块 B 具有全局变量X,则模块 A 将创建该名称的变量,其初始值为 B 所具有的模块导入时其名称的变量。但是其中一个模块中对X的更改不会反映在另一个模块中。

假设X确实在 B 中发生变化,但我们希望 A 中的代码能够在 B 中获取X的最新值。我们可以通过在 B 中包含一个名为 GetX()的函数来实现。假设 A B 导入了所有内容,那么 A 将获得一个函数 GetX(),这是一个副本 B 该名称的功能,其唯一目的是返回X的值。除非 B 更改该功能(这是可能的,例如可以分配功能) ,两个模块中的函数将始终相同,因此 A 可以使用其函数在 B 中获取X的值。

答案 2 :(得分:1)

Python全局变量不是全局的

正如wassimans指出的那样,它们本质上属于它们所定义的模块范围内的属性(或包含定义它们的函数的模块)。

人们遇到的第一个困惑(bug)没有意识到函数具有本地名称空间,并且在函数中设置变量使得它成为函数的本地函数,即使它们打算用于更改(全局)变量封闭模块中的相同名称。 (宣布这个名字 在一个全球性的'函数中的语句,或在设置之前访问(全局)变量。)

人们遇到的第二个困惑(bug)是每个模块(即导入的文件)都包含自己所谓的“全局”模块。名称空间。我猜python是世界(地球)的模块 - 也许我们正在寻找“通用”这个模块。跨越多个地球的变量。

第三个混乱(我现在开始理解)是'全局'在__main__模块中?即,如果以交互模式从命令行启动python,或者如果调用python脚本(从命令shell键入foo.py的名称) - 则不会导入可以使用其名称的模块。

' globals()'的内容或者globals()。keys() - 它给出了一个全局变量列表 - 似乎可以访问:dir(sys.modules [' __main__']) 似乎加载的python脚本(或没有加载脚本的交互式会话)的模块(名称为__name__)的模块没有全局名称,但可以作为名称为'的模块访问。 __main__'在系统的所有活动模块列表中,sys.modules