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

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


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


当前回答

尽管这已经得到了回答,但我还是再次给出了解决方案,因为我更喜欢单线这是如果您希望在函数中创建全局变量

def someFunc():
    x=20
    globals()['y']=50
someFunc() # invoking function so that variable Y is created globally 
print(y) # output 50
print(x) #NameError: name 'x' is not defined as x was defined locally within function

其他回答

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

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每次在函数内部分配新名称时都需要执行至少三次名称查找(以确保该名称在模块/内置级别上不存在),这将大大降低非常常见的操作速度。)

对于并行执行,如果您不了解正在发生的情况,全局变量可能会导致意外的结果。下面是在多处理中使用全局变量的示例。我们可以清楚地看到,每个过程都使用自己的变量副本:

import multiprocessing
import os
import random
import sys
import time

def worker(new_value):
    old_value = get_value()
    set_value(random.randint(1, 99))
    print('pid=[{pid}] '
          'old_value=[{old_value:2}] '
          'new_value=[{new_value:2}] '
          'get_value=[{get_value:2}]'.format(
          pid=str(os.getpid()),
          old_value=old_value,
          new_value=new_value,
          get_value=get_value()))

def get_value():
    global global_variable
    return global_variable

def set_value(new_value):
    global global_variable
    global_variable = new_value

global_variable = -1

print('before set_value(), get_value() = [%s]' % get_value())
set_value(new_value=-2)
print('after  set_value(), get_value() = [%s]' % get_value())

processPool = multiprocessing.Pool(processes=5)
processPool.map(func=worker, iterable=range(15))

输出:

before set_value(), get_value() = [-1]
after  set_value(), get_value() = [-2]
pid=[53970] old_value=[-2] new_value=[ 0] get_value=[23]
pid=[53971] old_value=[-2] new_value=[ 1] get_value=[42]
pid=[53970] old_value=[23] new_value=[ 4] get_value=[50]
pid=[53970] old_value=[50] new_value=[ 6] get_value=[14]
pid=[53971] old_value=[42] new_value=[ 5] get_value=[31]
pid=[53972] old_value=[-2] new_value=[ 2] get_value=[44]
pid=[53973] old_value=[-2] new_value=[ 3] get_value=[94]
pid=[53970] old_value=[14] new_value=[ 7] get_value=[21]
pid=[53971] old_value=[31] new_value=[ 8] get_value=[34]
pid=[53972] old_value=[44] new_value=[ 9] get_value=[59]
pid=[53973] old_value=[94] new_value=[10] get_value=[87]
pid=[53970] old_value=[21] new_value=[11] get_value=[21]
pid=[53971] old_value=[34] new_value=[12] get_value=[82]
pid=[53972] old_value=[59] new_value=[13] get_value=[ 4]
pid=[53973] old_value=[87] new_value=[14] get_value=[70]

除了已经存在的答案之外,为了使这一问题更加令人困惑:

在Python中,仅在函数内部引用的变量是隐式全局。如果在任何地方为变量分配了新值在函数体中,假设它是局部的。如果变量如果在函数中分配了一个新值,则变量为隐式本地,您需要将其显式声明为“全局”。虽然一开始有点令人惊讶,但片刻的思考解释了这一方面,要求全局分配变量提供了防止意外的副作用。另一方面,如果全球对于所有全局引用都是必需的时间您必须将对内置函数或导入模块的组件。这种混乱会破坏全球宣言对识别副作用。

来源:Python中局部和全局变量的规则是什么?。

事实证明,答案总是很简单。

下面是一个小示例模块,它以一种简单的方式在主定义中显示:

def five(enterAnumber,sumation):
    global helper
    helper  = enterAnumber + sumation

def isTheNumber():
    return helper

以下是如何在主要定义中显示它:

import TestPy

def main():
    atest  = TestPy
    atest.five(5,8)
    print(atest.isTheNumber())

if __name__ == '__main__':
    main()

这个简单的代码就是这样工作的,它会执行。我希望这有帮助。