在创build它们的函数中使用全局variables
如果我在一个函数中创build一个全局variables,我怎样才能在另一个函数中使用该variables?
我是否需要将全局variables存储在需要访问的函数的局部variables中?
您可以在其他函数中使用全局variables,方法是在分配给它的每个函数中将其声明为全局variables:
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
我想这是因为全局variables非常危险,所以Python希望通过明确地要求global
关键字来确保你确实知道你在玩什么。
如果你想跨模块共享一个全局variables,请参阅其他答案。
如果我正确地理解你的情况,你看到的是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
这里发生的事情是,Python假定在函数中任何地方分配的任何名称都是该函数的本地名字,除非明确地告知。 如果只是从名称中读取 ,名称不在本地,则会尝试在任何包含的范围(例如模块的全局范围)中查找名称。
因此,当将名称分配给名称myGlobal
时,Python将创build一个局部variables,该局部variables会myGlobal
同名全局variables。 当func1()
返回时,本地超出范围并被垃圾收集 ; 与此同时, func2()
永远不会看到(未修改的)全局名称以外的任何东西。 请注意,这个命名空间的决定发生在编译时,而不是在运行时 – 如果您在分配给func1()
之前读取myGlobal
的值, myGlobal
得到一个UnboundLocalError
,因为Python已经决定它必须是一个局部variables,但它还没有任何相关的值。 但是通过使用“ global
”语句,您告诉Python它应该在别处查找名称,而不是在本地分配。
(我相信这种行为主要是通过优化本地命名空间而产生的 – 如果没有这种行为,Python的虚拟机将需要至less执行三次名称查找,每次在函数内部分配一个新名称(以确保名称不会被忽略) t已经存在于模块/内置级),这将显着减慢一个非常常见的操作。)
您可能想要探索命名空间的概念。 在Python中, 模块是全局数据的自然之处:
每个模块都有自己的专用符号表,它被模块中定义的所有函数用作全局符号表。 因此,模块的作者可以在模块中使用全局variables,而不必担心与用户的全局variables发生意外冲突。 另一方面,如果你知道自己在做什么,你可以使用与之相同的符号来引用模块的全局variables
modname.itemname
。
这里描述了模块中的全局variables的一个具体用法 – 模块间variables – 如何分享 – 全局variables – 跨模块 :
在单个程序中跨模块共享信息的规范方法是创build一个特殊的configuration模块(通常称为config或cfg)。 只需在应用程序的所有模块中导入configuration模块; 该模块将成为全球名称。 由于每个模块只有一个实例,所以对模块对象所做的任何更改都会反映到各处。 例如:
文件: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使用一个简单的启发式来决定它应该从local和global之间加载一个variables的范围。 如果variables名称出现在赋值的左侧,但未声明为全局variables名称,则假定为本地variables名称。 如果它不出现在任务的左侧,则认为是全局的。
>>> 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
variables。
如果要在函数中引用全局variables,则可以使用global关键字来声明哪些variables是全局variables。 在任何情况下都不需要使用它(如某人在这里错误地声称) – 如果expression式中引用的名称不能在本地作用域或定义该函数的函数中的作用域中find,则可以在全局variables。
但是,如果在函数中分配了一个未声明为全局variables的新variables,则该variables将隐式声明为本地variables,并且可能会遮盖任何具有相同名称的现有全局variables。
而且,全局variables是有用的,与一些OOP狂热者相反 – 特别是对于OOP过度的小脚本。
除了已经存在的答案,并使之更加混乱:
在Python中,仅在函数内引用的variables隐式地是全局的 。 如果一个variables在函数体内的任何地方被分配了一个新的值,那么它被认为是本地的 。 如果一个variables在函数内部被分配了一个新的值,这个variables就是隐式的局部variables,你需要明确地声明它是“全局的”。
起初虽然有点出人意料,但是一会儿的考虑就解释了这一点。 一方面,要求分配variables的全局值可以防止出现意想不到的副作用。 另一方面,如果所有全局引用都需要全局的话,那么您就一直在使用全局。 您必须将每个对内置函数的引用或导入模块的组件声明为全局。 这种混乱将破坏全球声明确定副作用的有效性。
来源: Python中的局部和全局variables的规则是什么? 。
如果我在一个函数中创build一个全局variables,我怎样才能在另一个函数中使用该variables?
我们可以创build一个具有以下function的全局:
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()
使用全局variables
你可以使用它,只要你不希望改变它指向的对象:
例如,
def use_global_variable(): return global_variable + '!!!'
现在我们可以使用全局variables:
>>> use_global_variable() 'Foo!!!'
从函数内部修改全局variables
要将全局variables指向另一个对象,则需要再次使用global关键字:
def change_global_variable(): global global_variable global_variable = 'Bar'
请注意,在写这个函数之后,实际改变它的代码仍然没有运行:
>>> use_global_variable() 'Foo!!!'
所以在调用函数之后:
>>> change_global_variable()
我们可以看到全局variables已经被改变了。 global_variable
名称现在指向'Bar'
:
>>> use_global_variable() 'Bar!!!'
请注意,Python中的“全局”不是真正的全局 – 它只是模块级别的全局。 所以它只适用于在全局模块中编写的函数。 函数记住它们被写入的模块,所以当它们被导出到其他模块中时,它们仍然在它们被创build的模块中寻找全局variables。
具有相同名称的局部variables
如果你创build一个具有相同名字的局部variables,将会掩盖一个全局variables:
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!!!'
但是使用这个错误的局部variables不会改变全局variables:
>>> use_global_variable() 'Bar!!!'
注意你应该避免使用与globals同名的局部variables,除非你确切地知道你在做什么,并有一个很好的理由这样做。 我还没有遇到这样的一个原因。
在并行执行的情况下,如果不了解发生了什么,全局variables可能会导致意外的结果。 这是一个在多处理中使用全局variables的例子。 我们可以清楚地看到每个进程都使用自己的variables副本:
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]
你实际上并不是将全局存储在本地variables中,只是创build一个到原始全局引用引用的同一对象的本地引用。 请记住,Python中几乎所有的东西都是引用对象的名称,在正常的操作中没有任何东西被复制。
如果您不必明确指定标识符是指何时引用预定义的全局variables,那么您可能必须明确指定标识符是否为新的局部variables(例如,使用“var”命令在JavaScript中看到)。 由于局部variables在任何严重和非平凡的系统中比全局variables更普遍,所以在大多数情况下,Python的系统更有意义。
你可以用一个试图猜测的语言,如果存在的话使用一个全局variables,或者如果没有的话创build一个局部variables。 但是,这将是非常容易出错的。 例如,导入另一个模块可能会通过该名称无意中引入一个全局variables,从而改变程序的行为。
您需要在您要使用的每个函数中引用全局variables。
如下:
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] """
你所说的是使用这样的方法:
globvar = 5 def f(): var = globvar print(var) f()** # Prints 5
但更好的方法是使用这样的全局variables:
globavar = 5 def f(): global globvar print(globvar) f() #prints 5
两者都提供相同的输出。
事实certificate,答案总是很简单。
这是一个小样本模块。 这是一个在主要定义中显示的方法:
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()
这个简单的代码就像那样,就会执行。 我希望它有帮助。
尝试这个:
def x1(): global x x = 6 def x2(): global x x = x+1 print x x = 5 x1() x2()
继续和作为一个附加,使用一个文件来包含所有本地声明的全局variables,然后“导入为”:
文件initval.py
Stocksin = 300 Prices = []
文件getstocks.py
import initval as iv Def getmystocks (): iv.Stocksin = getstockcount () Def getmycharts (): For ic in range (0,iv.Stocksin):
…..
写入全局数组的显式元素并不需要全局声明,尽pipe写入“批发”的确有这样的要求:
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
如果你有一个同名的局部variables,你可能想要使用globals()
函数 。
globals()['your_global_var'] = 42
引用您希望显示更改的类名称空间。
在这个例子中,runner使用文件config中的max 。 当跑步者使用它时,我想让我的testing改变最大值 。
主/ config.py
max = 15000
主/ runner.py
from main import config def check_threads(): return max < thread_count
testing/ 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
只是让你转储/加载variables进出全局命名空间。 超级方便,没有麻烦,没有大惊小怪。 很确定它只是python 3。