8

好的,所以我遇到了一个非常烦人的问题,即在本地设置了一个变量,但在该函数之外又恢复为原来的自我(在这种情况下为无),但同时我可以操纵其他变量,并且仍然可以不使用“全局”关键字。

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

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 

请注意,所有的操作foofoo_foo工作都很好,但是当我调用 bar 时仍然是 None print_the_bar,并且我的代码中有很多打印语句来验证里面的 bardo_update_task确实具有正确的值并且不是 None。

有人可以向我解释为什么会这样吗?

4

4 回答 4

15

如果只需要在函数中读取全局变量的值,则不需要 global 关键字:

x = 3
def f():
    print x

如果您曾经设置过全局变量的值,则需要使用关键字,这样您就不会创建局部变量:

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

f()
print x
于 2012-08-08T15:06:05.687 回答
8

当您对 foo 和 foo_foo 执行操作时,您不会更改引用:

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

foo仍然指代同一个对象;它刚刚包含更多数据。

bar = ['key', 'value']

重新分配 bar以引用一个新对象(具有两个元素的列表)。

但是,当在函数中遇到该行时,它会创建一个本地引用bar,除非您说global bar. 实际上,您有两个不同bar的变量名为:全局变量和局部变量。

Sayingglobal 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']
于 2012-08-08T15:05:22.550 回答
0

您可以在函数内从全局范围读取变量,但如果不使用“global”关键字,则无法修改它们的值。

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

尽管您可以读取 globalbar的值,但是一旦您尝试从函数中重新为其分配值,您实际上已经创建了一个新值bar并且没有对全局值进行操作。

于 2012-08-08T15:13:19.570 回答
0

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

于 2012-08-08T15:01:32.083 回答