我什么时候需要在python中使用全局关键字
好吧,我遇到了一个非常恼人的问题,一个变量在本地被设置,但在函数外部又恢复到原来的状态(在本例中为None),但同时我可以操作其他变量,并且仍然可以不使用“global”关键字 我无法提供这方面的真实代码,但它是这样的:我什么时候需要在python中使用全局关键字,python,Python,好吧,我遇到了一个非常恼人的问题,一个变量在本地被设置,但在函数外部又恢复到原来的状态(在本例中为None),但同时我可以操作其他变量,并且仍然可以不使用“global”关键字 我无法提供这方面的真实代码,但它是这样的: foo = {} foo_foo = {} bar = None def changes_foo(): ...do some stuff to foo... class EditThread(threading.Thread): def __init__
foo = {}
foo_foo = {}
bar = None
def changes_foo():
...do some stuff to foo...
class EditThread(threading.Thread):
def __init__(self):
setup()
def run(self):
for key, value in foo.items():
do_update_task(key, value)
def do_update_task(self, key, value):
...do some editing too foo...
del foo[key]
bar = [key, value]
foo_foo[key] = value
def print_the_bar():
print bar
请注意,foo
和foo\u foo
上的所有操作都很好,但是当我调用print\u the\u bar
时,bar仍然没有,我的代码中有很多print语句来验证do\u update\u task
中的bar确实具有正确的值,并且不是空的
有人能解释一下为什么会这样吗?您在函数中定义的变量只能从函数体访问。当您对foo和foo\u foo执行操作时,您不会更改引用:
foo = {}
foo['key'] = 'stuff'
foo
仍指与以前相同的对象;它刚才包含了更多的数据
bar = ['key', 'value']
这将重新分配条
以引用新对象(包含两个元素的列表)
但是,在函数中遇到该行时,它会创建一个本地引用条,除非您说全局条。实际上,有两个不同的变量名为bar
:全局变量和局部变量
说出global bar
告诉Python使用bar
的全局版本,而不是使用相同的名称创建新的局部变量
通常,如果要修改全局变量,应为每个变量声明global varname
,以避免意外创建局部变量
或者,您可以使用一个类:
class State(object):
def __init__(self):
self.foo = {}
self.foo_foo = {}
self.bar = None
state = State()
def fn():
state.bar = ['key', 'value']
如果只需要读取函数中全局变量的值,则不需要全局关键字:
x = 3
def f():
print x
如果设置全局变量的值,则需要使用关键字,以便不创建局部变量:
x = 3
def f():
global x
x = 5
f()
print x
您可以从函数中的全局范围读取变量,但如果不使用“global”关键字,则无法修改其值
当您尝试设置bar=[key,value]
时,一个新的bar
变量将添加到函数的命名空间中。从那时起,bar
引用这个新变量,而不是全局变量
虽然您可以读取全局条
的值,但一旦尝试从函数中重新为其赋值,实际上,您已经创建了一个新的条形图
,并且没有对全局条形图进行操作。相关:我的观点是,我仍然可以对foo和foo\u foo进行更改,但当我对条形图进行更改时,它只会在本地范围内进行。我非常愿意接受我不是一个经验丰富的pythonista,我的问题是为什么我总是犯这个错误。“有人能给我解释一下为什么会这样吗?”用两个词:变量范围。换句话说:“什么时候我需要一个全局变量?”——只有当你需要重新思考你的程序设计时。是的,是的,我们现在都知道全局变量是纯粹的邪恶…:p谢谢你给我一个很好的答案,解释原因。我会尽快接受你的答案。+1是唯一一个没有声明你不能在没有global关键字的情况下修改全局变量的答案;当然,您可以修改它们,只是不能用=
@Wooble Good point全局地重新绑定名称。。我想我会删除我的答案,只是基于这个:)谢谢,这个差异对我来说真的很有启发性+1.简洁明了。还可以了解这一点在词典中的作用。了解为名称赋值(x=5
)和变异(通常伪装为x[…]=5
)之间的区别是理解Python工作原理的基础。