myGlobal = "hello"
def changeGlobal():
myGlobal="bye"
from first import *
changeGlobal()
print myGlobal
我得到的输出是
您好
虽然我认为应该是
再见
为什么在调用myGlobal
函数后全局变量changeGlobal()
没有变化?
答案 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