Python 带导入的全局变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4706879/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 17:05:40  来源:igfitidea点击:

Global variable with imports

pythonglobal

提问by Joel

first.py

第一个.py

myGlobal = "hello"

def changeGlobal():
   myGlobal="bye"

second.py

第二个.py

from first import *

changeGlobal()
print myGlobal

The output I get is

我得到的输出是

hello

你好

although I thought it should be

虽然我认为应该是

bye

再见

Why doesn't the global variable myGlobalchanges after the call to the changeGlobal()function?

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

回答by TryPyPy

Try:

尝试:

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

Actually, that doesn't work either. When you import *, you create a new localmodule global myGlobalthat is immune to the change you intend (as long as you're not mutating the variable, see below). You can use this instead:

实际上,这也行不通。当您import *创建一个新的本地模块 global 时myGlobal,它不受您想要的更改的影响(只要您不改变变量,请参见下文)。您可以改用它:

import nice

nice.changeGlobal()
print nice.myGlobal

Or:

或者:

myGlobal = "hello"

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

changeGlobal()

However, if your global is a mutable container, you're now holding a reference to a mutable and are able to see changes done to it:

但是,如果您的全局变量是一个可变容器,那么您现在持有一个对可变变量的引用,并且能够看到对它所做的更改:

myGlobal = ["hello"]

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

回答by wassimans

I had once the same concern as yours and reading the following section from Norman Matloff's Quick and Painless Python Tutorialwas really a good help. Here is what you need to understand (copied from Matloff's book):

我曾经和你有过同样的担忧,阅读Norman MatloffQuick and Painless Python 教程中的以下部分真的很有帮助。这是您需要了解的内容(从 Matloff 的书中复制):

Python does not truly allow global variables in the sense that C/C++ do. An imported Python module will not have direct access to the globals in the module which imports it, nor vice versa.

在 C/C++ 允许的意义上,Python 并没有真正允许全局变量。导入的 Python 模块将无法直接访问导入它的模块中的全局变量,反之亦然。

For instance, consider these two files, x.py,

例如,考虑这两个文件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()

and y.py:

y.py

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

The variable x in x.pyis visible throughout the module x.py, but not in y.py. In fact, execution of the line x += 1

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

in the latter will cause an error message to appear, “global name 'x' is not defined.”

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

Indeed, a global variable in a module is merely an attribute (i.e. a member entity) of that module, similar to a class variable's role within a class. When module Bis imported by module A, B's namespace is copied to A's. If module Bhas a global variable X, then module Awill create a variable of that name, whose initial value is whatever module Bhad for its variable of that name at the time of importing. But changes to X in one of the modules will NOT be reflected in the other.

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

Say X does change in B, but we want code in Ato be able to get the latest value of X in B. We can do that by including a function, say named GetX()in B. Assuming that Aimported everything from B, then Awill get a function GetX()which is a copy of B's function of that name, and whose sole purpose is to return the value of X. Unless Bchanges that function (which is possible, e.g. functions may be assigned), the functions in the two modules will always be the same, and thus Acan use its function to get the value of X in B.

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

回答by Ribo

Python global variables are not global

Python 全局变量不是全局变量

As wassimans points out above they are essentially attributes within the scope of the module they are defined in (or the module that contains the function that defined them).

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

The first confusion(bug) people run into is not realizing that functions have a local name space and that setting a variable in a function makes it a local to the function even when they intended for it to change a (global) variable of the same name in the enclosing module. (declaring the name in a 'global' statement in the function, or accessing the (global) variable before setting it.)

人们遇到的第一个困惑(错误)是没有意识到函数具有本地名称空间,并且在函数中设置变量使其成为函数的本地变量,即使他们打算更改相同的(全局)变量封闭模块中的名称。(在函数的“全局”语句中声明名称,或在设置之前访问(全局)变量。)

The second confusion(bug) people run into is that each module (ie imported file) contains its own so called 'global' name space. I guess python things the world(globe) is the module -- perhaps we are looking for 'universal' variables that span more than one globe.

人们遇到的第二个困惑(错误)是每个模块(即导入的文件)都包含自己所谓的“全局”命名空间。我猜 python 的东西 world(globe) 是模块——也许我们正在寻找跨越多个地球的“通用”变量。

The third confusion (that I'm starting to understand now) is where are the 'globals' in the __main__module? Ie if you start python from the command line in interactive mode, or if you invoke python script (type the name of the foo.py from the command shell) -- there is no import of a module whose name you can use.

第三个困惑(我现在开始理解了)是__main__模块中的“全局变量”在哪里?即,如果您以交互模式从命令行启动 python,或者如果您调用 python 脚本(从命令外壳输入 foo.py 的名称)-- 没有导入您可以使用其名称的模块。

The contents of 'globals()' or globals().keys() -- which gives you a list of the globals -- seems to be accessible as: dir(sys.modules['__main__']) It seems that the module for the loaded python script (or the interactive session with no loaded script), the one named in: __name__, has no global name, but is accessible as the module whose name is '__main__' in the system's list of all active modules, sys.modules

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