题
我怎么可以创造或使用全球变量的功能?
如果我创建一个全球性变量的一个函数,如何可以我用的全球变中的另一个功能?我需要储存的全球变中的局部变量的功能,需要其访问?
解决方案
您可以在其他函数中使用全局变量,在每个分配给它的函数中将其声明为 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
关键字来确保你真正知道你正在玩的是什么。 / p>
如果您想跨模块共享全局变量,请参阅其他答案。
其他提示
如果我理解你的情况正确的话,你现在看到的结果是Python如何处理当地的(功能)和全球(模块)的名称空间。
说你已经有了一个模块是这样的:
# sample.py
myGlobal = 5
def func1():
myGlobal = 42
def func2():
print myGlobal
func1()
func2()
你可能会想到这个打印42,但是它打印5.正如已经提到的,如果添加一个'global
'宣言》 func1()
, 然后 func2()
将印42.
def func1():
global myGlobal
myGlobal = 42
什么这里是蟒蛇假定的任何名称是 分配给, ,任何地方在一个功能,是本地的功能,除非有明确的告诉。如果只是 阅读 从一个名称,名称不存在当地,它会试试看的名字在任何包含范围(例如该模块的全球范围).
当你分配42名称 myGlobal
, 因此,蟒蛇创建一个本地的变阴影的全球变量的相同的名称。这地方超出范围,并是 垃圾回收 时 func1()
返回;与此同时, func2()
可以永远看不到任何东西比(未经修改)全球名称。注意,这个名字空间决定在编制时间,而不是在运行时-如果你要读的价值 myGlobal
内部 func1()
在你之前分配给它,你就会得到一个 UnboundLocalError
, 因为蟒蛇已经决定,它必须是一个地方变量,但没有任何价值与其相关联的。但是,通过使用'global
'声明,你告诉蟒蛇,它应该看看其他地方的名称而不是分配到它在本地。
(我认为,这种行为起源于主要通过优化当地的名字空间--没有这种行为,蟒蛇的虚拟机会需要执行至少三名称查找,每次一个新的名称是分配给内部的功能(确保这个名字没有已经存在模块/builtin的水平),这将大大缓慢下来的一个非常常见的运作。)
您可能想要探索名称空间的概念。在Python中,模块是全球的自然场所数据:
每个模块都有自己的私有符号表,该表用作模块中定义的所有函数的全局符号表。因此,模块的作者可以在模块中使用全局变量,而不必担心与用户的全局变量的意外冲突。另一方面,如果您知道自己在做什么,可以触摸模块的全局变量,使用相同的符号来表示其函数,
modname.itemname
。
此处描述了全局模块的具体用法 - 如何跨模块共享全局变量?,为了完整性,内容在此处共享:
在单个程序中跨模块共享信息的规范方法是创建一个特殊的配置模块(通常称为 config 或 cfg )。只需在应用程序的所有模块中导入配置模块;然后该模块可用作全局名称。因为每个模块只有一个实例,所以对模块对象所做的任何更改都会在任何地方反映出来。例如:
文件:config.py
x = 0 # Default value of the 'x' configuration setting
档案:mod.py
import config config.x = 1
档案:main.py
import config import mod print config.x
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
>>>
查看 foo()
中赋值左侧的baz是唯一的 LOAD_FAST
变量。
如果要在函数中引用全局变量,可以使用全局关键字来声明哪些变量是全局变量。您不必在所有情况下都使用它(因为此处有人错误地声称) - 如果表达式中引用的名称无法在定义此函数的函数的本地范围或范围中找到,则在全局范围内查找变量
但是,如果在函数中分配一个未声明为全局变量的新变量,它将被隐式声明为local,并且它可以掩盖任何具有相同名称的现有全局变量。
此外,全局变量是有用的,与一些声称不同的OOP狂热者相反 - 特别是对于较小的脚本,其中OOP过度。
除了已经存在的答案并使其更加混乱:
在Python中,仅在函数内引用的变量是 隐式全球。如果在任何地方为变量分配了新值 在功能体内,它被认为是本地。如果是变量 在函数内部分配了一个新值,变量是 隐式本地,你需要明确地将其声明为‘ global’。
虽然起初有点令人惊讶,但片刻的考虑解释了 这个。一方面,要求全局分配变量提供了一个 禁止意外的副作用。另一方面,如果全球化了 所有全球参考文献都需要,您将全局使用全局参考文献 时间。您必须声明为内置的每个引用的全局 功能或导入模块的组件。这种混乱会 打败全球宣言的有用性 副作用。
来源: Python中的局部变量和全局变量有哪些规则? 。
如果我在一个函数中创建一个全局变量,我该如何在另一个函数中使用该变量?
我们可以使用以下功能创建一个全局:
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
函数:
>>> create_global_variable()
使用不修改的全局变量
您可以使用它,只要您不希望更改它指向的对象:
例如,
def use_global_variable():
return global_variable + '!!!'
现在我们可以使用全局变量:
>>> use_global_variable()
'Foo!!!'
从函数内部修改全局变量
要将全局变量指向其他对象,您需要再次使用global关键字:
def change_global_variable():
global global_variable
global_variable = 'Bar'
请注意,在编写此函数后,实际更改它的代码仍未运行:
>>> change_global_variable()
所以在调用函数后:
>>> use_global_variable()
'Bar!!!'
我们可以看到全局变量已被更改。 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!!!'
请注意“全球”在Python中并不是真正的全局 - 它只是模块级别的全局。因此它仅适用于在全局模块中编写的函数。函数会记住编写它们的模块,因此当它们导出到其他模块时,它们仍会查看创建它们的模块以查找全局变量。
具有相同名称的本地变量
如果您创建一个具有相同名称的局部变量,它将掩盖一个全局变量:
<*>但是使用那个名不见经传的局部变量并不会改变全局变量:
<*>请注意,除非您确切地知道自己在做什么并且有充分的理由这样做,否则应该避免使用与globals同名的局部变量。我还没有遇到这样的原因。
对于并行执行,如果您不了解发生的情况,全局变量可能会导致意外结果。以下是在多处理中使用全局变量的示例。我们可以清楚地看到每个进程都使用自己的变量副本:
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]
事实证明答案总是很简单。
这是一个小样本模块,其中有一种简单的方法可以在 main
定义中显示它:
def five(enterAnumber,sumation):
global helper
helper = enterAnumber + sumation
def isTheNumber():
return helper
以下是如何在 main
定义中显示它:
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
但更好的方法是使用这样的全局变量:
globavar = 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]
"""
您实际上并未将全局存储在局部变量中,只是创建对原始全局引用所引用的同一对象的本地引用。请记住,Python中的所有内容都是一个引用对象的名称,并且在通常的操作中不会复制任何内容。
如果您不必明确指定标识符何时引用预定义的全局,那么您可能必须明确指定标识符何时是新的局部变量(例如,使用类似'的'在JavaScript中看到的var'命令)。由于局部变量在任何严重且非平凡的系统中比全局变量更常见,因此Python的系统在大多数情况下更有意义。
你可能有一种试图猜测的语言,使用全局变量(如果存在)或创建局部变量(如果不存在)。但是,这很容易出错。例如,导入另一个模块可能会无意中引入该名称的全局变量,从而改变程序的行为。
试试这个:
def x1():
global x
x = 6
def x2():
global x
x = x+1
print x
x = 5
x1()
x2() # output --> 7
如果你有一个同名的局部变量,你可能想要使用 globals()
功能。
globals()['your_global_var'] = 42
继续之后,作为一个补充,使用一个文件来包含所有在本地声明的全局变量,然后 import as
:
文件 initval.py :
Stocksin = 300
Prices = []
文件 getstocks.py :
import initval as iv
def getmystocks():
iv.Stocksin = getstockcount()
def getmycharts():
for ic in range(iv.Stocksin):
写入全局数组的显式元素显然不需要全局声明,尽管写入它“批发”确实有这个要求:
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
引用要在其中显示更改的类命名空间。
在此示例中,跑步者正在使用文件配置中的 max 。我想让我的测试在跑步者使用时改变 max 的值。
主要/ config.py 强>
max = 15000
主要/ runner.py 强>
from main import config
def check_threads():
return max < thread_count
<强>测试/ runner_test.py 强>
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()
我添加了这个,因为我没有在任何其他答案中看到它,它可能对某些类似的东西挣扎有用。 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
和
from pickle import dump
def dumpfile(name):
with open(name+".dat", "wb") as outfile:
dump(globals()[name], outfile)
return True
只允许您将变量转储/加载到全局命名空间中。超级方便,没有麻烦,没有大惊小怪。很确定它只是Python 3。