如何在函数中创建或使用全局变量?

如何在其他函数中使用一个函数中定义的全局变量?


未能在适当的地方使用全局关键字通常会导致UnboundLocalError。在第一次使用后重新分配局部变量时,UnboundLocalError中解释了这方面的精确规则。一般来说,当寻求解释时,请将其他问题作为该问题的副本,当某人只需要知道全局关键字时,请关闭该问题。


当前回答

类似此代码:

myVar = 12

def myFunc():
  myVar += 12

Key:

如果在字符串外部声明变量,它将变为全局变量。

如果在字符串中声明变量,它将变为本地变量。

如果要在字符串中声明全局变量,请在要声明的变量之前使用关键字global:

myVar = 124
def myFunc():
  global myVar2
  myVar2 = 100
myFunc()
print(myVar2)

然后文档中有100个。

其他回答

Python使用一个简单的启发式方法来决定应该从哪个范围加载变量,在本地和全局之间。如果变量名出现在赋值的左侧,但未声明为全局变量,则假定它是局部变量。如果它没有出现在赋值的左侧,则假定它是全局的。

>>> import dis
>>> def foo():
...     global bar
...     baz = 5
...     print bar
...     print baz
...     print quux
... 
>>> dis.disassemble(foo.func_code)
  3           0 LOAD_CONST               1 (5)
              3 STORE_FAST               0 (baz)

  4           6 LOAD_GLOBAL              0 (bar)
              9 PRINT_ITEM          
             10 PRINT_NEWLINE       

  5          11 LOAD_FAST                0 (baz)
             14 PRINT_ITEM          
             15 PRINT_NEWLINE       

  6          16 LOAD_GLOBAL              1 (quux)
             19 PRINT_ITEM          
             20 PRINT_NEWLINE       
             21 LOAD_CONST               0 (None)
             24 RETURN_VALUE        
>>> 

看看baz(出现在foo()赋值的左侧)是如何成为唯一的LOAD_FAST变量的。

写入全局数组的显式元素显然不需要全局声明,尽管“批发”写入它确实有这样的要求:

import numpy as np

hostValue = 3.14159
hostArray = np.array([2., 3.])
hostMatrix = np.array([[1.0, 0.0],[ 0.0, 1.0]])

def func1():
    global hostValue    # mandatory, else local.
    hostValue = 2.0

def func2():
    global hostValue    # mandatory, else UnboundLocalError.
    hostValue += 1.0

def func3():
    global hostArray    # mandatory, else local.
    hostArray = np.array([14., 15.])

def func4():            # no need for globals
    hostArray[0] = 123.4

def func5():            # no need for globals
    hostArray[1] += 1.0

def func6():            # no need for globals
    hostMatrix[1][1] = 12.

def func7():            # no need for globals
    hostMatrix[0][0] += 0.33

func1()
print "After func1(), hostValue = ", hostValue
func2()
print "After func2(), hostValue = ", hostValue
func3()
print "After func3(), hostArray = ", hostArray
func4()
print "After func4(), hostArray = ", hostArray
func5()
print "After func5(), hostArray = ", hostArray
func6()
print "After func6(), hostMatrix = \n", hostMatrix
func7()
print "After func7(), hostMatrix = \n", hostMatrix

如果我正确理解了您的情况,那么您看到的是Python如何处理本地(函数)和全局(模块)命名空间的结果。

假设你有这样一个模块:

# sample.py
_my_global = 5

def func1():
    _my_global = 42

def func2():
    print _my_global

func1()
func2()

您可能希望它打印42,但实际上它打印5。如上所述,如果向func1()添加一个“全局”声明,那么func2()将打印42。

def func1():
    global _my_global 
    _my_global = 42

这里发生的情况是,Python假设在函数中的任何地方,任何分配给的名称都是该函数的本地名称,除非另有明确说明。如果它只是从一个名称中读取,并且该名称在本地不存在,那么它将尝试在任何包含范围(例如模块的全局范围)中查找该名称。

因此,当将42指定给名称_my_global时,Python将创建一个局部变量,该变量将覆盖同名的全局变量。当func1()返回时,该local超出范围并被垃圾收集;同时,func2()只能看到(未修改的)全局名称。请注意,这个命名空间决定发生在编译时,而不是在运行时——如果在赋值之前读取func1()内部的_my_global值,则会得到UnboundLocalError,因为Python已经决定它必须是一个本地变量,但它还没有与之关联的任何值。但通过使用“global”语句,您告诉Python应该在其他地方查找名称,而不是在本地分配。

(我认为,这种行为主要源于对本地名称空间的优化——如果没有这种行为,Python的VM每次在函数内部分配新名称时都需要执行至少三次名称查找(以确保该名称在模块/内置级别上不存在),这将大大降低非常常见的操作速度。)

我补充了这一点,因为我在其他任何答案中都没有看到它,它可能对正在与类似问题作斗争的人有用。globals()函数返回一个可变的全局符号字典,您可以在其中“神奇地”使数据可用于代码的其余部分。例如:

from pickle import load
def loaditem(name):
    with open(r"C:\pickle\file\location"+"\{}.dat".format(name), "rb") as openfile:
        globals()[name] = load(openfile)
    return True

and

from pickle import dump
def dumpfile(name):
    with open(name+".dat", "wb") as outfile:
        dump(globals()[name], outfile)
    return True

将只允许您将变量转储/加载到全局命名空间中。超级方便,没有麻烦,没有麻烦。很确定它只是Python 3。

您需要在每个要使用的函数中引用全局变量。

如下:

var = "test"

def printGlobalText():
    global var #wWe are telling to explicitly use the global version
    var = "global from printGlobalText fun."
    print "var from printGlobalText: " + var

def printLocalText():
    #We are NOT telling to explicitly use the global version, so we are creating a local variable
    var = "local version from printLocalText fun"
    print "var from printLocalText: " + var

printGlobalText()
printLocalText()
"""
Output Result:
var from printGlobalText: global from printGlobalText fun.
var from printLocalText: local version from printLocalText
[Finished in 0.1s]
"""