2012-08-08 72 views
4

好吧,所以我有一个非常恼人的问题,其中一个变量在本地被设置,但在该函数之外被还原为它的旧自我(在这种情况下为无),但同时我可以操作其他变量,并且仍然可以不使用“全局”关键字。什么时候需要在python中使用全局关键字

我不能为此提供真正的代码,但它是这样的:

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_foo作品就好了,但酒吧仍是无当我打电话print_the_bar,而且我的代码中有很多打印语句来验证do_update_task内部的栏实际上是否具有正确的值并且不是无。

有人请向我解释为什么是这样吗?

+0

相关:http://stackoverflow.com/questions/423379/using-global-variables-in-a-function-other-than-the-one-that-c​​reated-them – SeanC 2012-08-08 15:01:03

+0

我的观点是,我仍然可以对foo和foo_foo进行更改,但是当我对bar进行更改时,它只会在本地范围内进行更新。我非常乐意接受我不是一个经验丰富的pythonista,我的问题是为什么我不断收到这个错误。 – 2012-08-08 15:05:08

+0

“有人可以向我解释为什么它是这样吗?”用两个词:变量范围。换句话说:[链接](http://docs.python.org/release/1.5.1p1/tut/scopes.html) – chucksmash 2012-08-08 15:06:06

回答

6

当你做的事情foo和foo_foo,你不改变基准:

foo = {} 
foo['key'] = 'stuff' 

foo仍然指向同一个对象之前;它现在只包含更多的数据。

bar = ['key', 'value'] 

重新分配bar指一个新的对象(该列表具有两个元件)。

然而,当一个函数内部遇到这一行,除非你说global bar创建本地参考bar。实际上,您有两个不同的变量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'] 
+0

谢谢你解释原因的好答案。我会尽快接受你的回答。 – 2012-08-08 15:09:26

+0

对于没有声明的唯一答案+1不能在没有全局关键字的情况下修改全局变量;当然你可以修改它们,你不能用'='全局地重新绑定这个名字。 – geoffspear 2012-08-08 15:29:51

+0

@Wooble好点..我想我会实际删除我的答案只是基于这个:) – Levon 2012-08-08 15:41:55

0

您在函数中定义的变量只能从此函数的主体中访问。

8

如果你只需要阅读函数中的全局变量的值,你不需要全局关键字:

x = 3 
def f(): 
    print x 

如果曾经设置一个全局变量的值,你需要的关键字,这样你就不能创建一个局部变量:

x = 3 
def f(): 
    global x 
    x = 5 

f() 
print x 
+0

谢谢,这种差异真的让我感受到! – Alex 2017-12-20 12:44:49

0

您可以从函数内的全局范围读取变量,但不能在不使用“全局”关键字的情况下修改其值。

当您尝试设置bar =[key, value]时,会将新的bar变量添加到您的函数的名称空间中。从那时起,bar引用这个新变量,而不是全局变量。

虽然您可以阅读全局bar的值,但是一旦您尝试从函数内为其重新分配一个值,您实际上已创建了一个新的bar并且不在全局范围内运行。

相关问题