Python 在函数中使用全局变量

Python 在函数中使用全局变量,python,global-variables,scope,Python,Global Variables,Scope,如何在函数中创建或使用全局变量 如果在一个函数中创建全局变量,如何在另一个函数中使用该全局变量?我是否需要将全局变量存储在需要其访问的函数的局部变量中?您可能需要了解全局变量的概念。在Python中,是全局数据的自然场所: 每个模块都有自己的专用符号表,该表由模块中定义的所有函数用作全局符号表。因此,模块的作者可以在模块中使用全局变量,而不用担心与用户的全局变量发生意外冲突。另一方面,如果您知道自己在做什么,您可以使用用于引用其函数的相同符号,modname.itemname来触摸模块的全局变量

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


如果在一个函数中创建全局变量,如何在另一个函数中使用该全局变量?我是否需要将全局变量存储在需要其访问的函数的局部变量中?

您可能需要了解全局变量的概念。在Python中,是全局数据的自然场所:

每个模块都有自己的专用符号表,该表由模块中定义的所有函数用作全局符号表。因此,模块的作者可以在模块中使用全局变量,而不用担心与用户的全局变量发生意外冲突。另一方面,如果您知道自己在做什么,您可以使用用于引用其函数的相同符号,
modname.itemname
来触摸模块的全局变量

此处描述了global-in-A-module的具体用途,为完整起见,此处共享内容:

在单个程序中跨模块共享信息的标准方法是创建一个特殊的配置模块(通常称为configcfg)。只需在应用程序的所有模块中导入配置模块;然后,该模块将成为可用的全局名称。因为每个模块只有一个实例,所以对模块对象所做的任何更改都会反映到所有地方。例如:

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
文件:config.py

文件:mod.py

文件:main.py


可以在其他函数中使用全局变量,方法是在为其赋值的每个函数中将其声明为
global

globvar = 0

def set_globvar_to_one():
    global globvar    # Needed to modify global copy of globvar
    globvar = 1

def print_globvar():
    print(globvar)     # No need for global declaration to read value of globvar

set_globvar_to_one()
print_globvar()       # Prints 1
我认为这样做的原因是,由于全局变量非常危险,Python希望通过显式地要求使用
global
关键字来确保您真正知道这就是您正在使用的


如果要在模块之间共享全局变量,请参阅其他答案。

如果要在函数中引用全局变量,可以使用全局关键字声明哪些变量是全局变量。您不必在所有情况下都使用它(这里有人错误地声称)-如果表达式中引用的名称在定义该函数的函数的局部作用域或作用域中找不到,则会在全局变量中查找该名称

但是,如果在函数中为未声明为全局的新变量赋值,则该变量将隐式声明为局部变量,并且它可以覆盖任何具有相同名称的现有全局变量


此外,全局变量也很有用,与一些OOP狂热者声称的相反——特别是对于较小的脚本,OOP是一种过激的行为。

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

假设您有这样一个模块:

# sample.py
myGlobal = 5

def func1():
    myGlobal = 42

def func2():
    print myGlobal

func1()
func2()
globvar = 5

def f():
    var = globvar
    print(var)

f()  # Prints 5
globvar = 5
def f():
    global globvar
    print(globvar)
f()   #prints 5
您可能希望它打印42,但它打印5。如前所述,如果将“
global
”声明添加到
func1()
,则
func2()
将打印42

def func1():
    global myGlobal
    myGlobal = 42
这里发生的事情是,Python假定在函数中的任何位置分配给的任何名称都是该函数的本地名称,除非明确地告知其他名称。如果它只读取一个名称,而该名称在本地不存在,它将尝试在任何包含范围(例如模块的全局范围)中查找该名称

因此,当您将42赋给名称
myGlobal
时,Python将创建一个局部变量,该局部变量将隐藏同名的全局变量。当
func1();同时,
func2()
只能看到(未修改的)全局名称。请注意,此名称空间决策发生在编译时,而不是在运行时——如果在分配给它之前读取
func1()
中的
myGlobal
值,则会得到一个
UnboundLocalError
,因为Python已经决定它必须是一个局部变量,但它还没有与之关联的任何值。但是通过使用“
global
”语句,您可以告诉Python应该在其他地方查找名称,而不是在本地为其赋值


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

您实际上并没有将全局变量存储在局部变量中,只是创建了一个对原始全局引用所引用的同一对象的局部引用。请记住,Python中几乎所有内容都是引用对象的名称,在通常的操作中不会复制任何内容

如果您不必显式指定标识符何时引用预定义的全局变量,那么您可能需要显式指定标识符何时是新的局部变量(例如,JavaScript中的“var”命令)。由于局部变量比全局变量在任何严肃和非平凡的系统中更常见,因此Python的系统在大多数情况下更有意义


您可以使用一种尝试猜测的语言,使用全局变量(如果存在)或创建局部变量(如果不存在)。然而,这很容易出错。例如,导入另一个模块可能会无意中引入一个名为该名称的全局变量,从而改变程序的行为。

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        
>>> 
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]
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()
globvar = 5

def f():
    var = globvar
    print(var)

f()  # Prints 5
globvar = 5
def f():
    global globvar
    print(globvar)
f()   #prints 5
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]
"""
Stocksin = 300
Prices = []
import initval as iv

def getmystocks(): 
    iv.Stocksin = getstockcount()


def getmycharts():
    for ic in range(iv.Stocksin):
def create_global_variable():
    global global_variable # must declare it to be a global first
    # modifications are thus reflected on the module's global scope
    global_variable = 'Foo' 
>>> create_global_variable()
def use_global_variable():
    return global_variable + '!!!'
>>> use_global_variable()
'Foo!!!'
def change_global_variable():
    global global_variable
    global_variable = 'Bar'
>>> use_global_variable()
'Foo!!!'
>>> change_global_variable()
>>> use_global_variable()
'Bar!!!'
def use_local_with_same_name_as_global():
    # bad name for a local variable, though.
    global_variable = 'Baz' 
    return global_variable + '!!!'

>>> use_local_with_same_name_as_global()
'Baz!!!'
>>> use_global_variable()
'Bar!!!'
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
globals()['your_global_var'] = 42
max = 15000
from main import config
def check_threads():
    return max < thread_count 
from main import runner                # <----- 1. add file
from main.runner import check_threads
class RunnerTest(unittest):
   def test_threads(self):
       runner.max = 0                  # <----- 2. set global 
       check_threads()
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
from pickle import dump
def dumpfile(name):
    with open(name+".dat", "wb") as outfile:
        dump(globals()[name], outfile)
    return True
import multiprocessing

counter = 0

def do(task_id):
    global counter
    counter +=1
    print(f'task {task_id}: counter = {counter}')

if __name__ == '__main__':

    pool = multiprocessing.Pool(processes=4)
    task_ids = list(range(4))
    pool.map(do, task_ids)
task 0: counter = 1
task 1: counter = 2
task 2: counter = 3
task 3: counter = 4
task 0: counter = 1
task 1: counter = 1
task 2: counter = 1
task 3: counter = 1
def declare_a_global_variable():
    global global_variable_1
    global_variable_1 = 1

# Note to use the function to global variables
declare_a_global_variable() 
global_variable_2 = 2
def declare_a_global_variable():
    global global_variable_1
    global_variable_1 = 1

# Note to use the function to global variables
declare_a_global_variable() 
global_variable_2 = 2

def print_variables():
    print(global_variable_1)
    print(global_variable_2)
print_variables() # prints 1 & 2
global_variable_1 = 1
global_variable_2 = 2

def update_variables():
    global global_variable_1
    global_variable_1 = 11
    global_variable_2 = 12 # will update just locally for this function

update_variables()
print(global_variable_1) # prints 11
print(global_variable_2) # prints 2
# declaring some global variables
variable = 'peter'
list_variable_1 = ['a','b']
list_variable_2 = ['c','d']

def update_global_variables():
    """without using global line"""
    variable = 'PETER' # won't update in global scope
    list_variable_1 = ['A','B'] # won't update in global scope
    list_variable_2[0] = 'C' # updated in global scope surprisingly this way
    list_variable_2[1] = 'D' # updated in global scope surprisingly this way

update_global_variables()

print('variable is: %s'%variable) # prints peter
print('list_variable_1 is: %s'%list_variable_1) # prints ['a', 'b']
print('list_variable_2 is: %s'%list_variable_2) # prints ['C', 'D']
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