Python全局变量在函数中的if语句评估时不起作用

2 投票
1 回答
5708 浏览
提问于 2025-04-18 09:04

示例 1:

a=1
def b():
    print a
    a=2
    print a

示例 2:

a=1
def b():
    print a
    if a==1:
        a=2
    print a

示例 1 按预期工作,而示例 2 在第一次打印 a 时出错,提示 UnboundLocalError: 本地变量 'a' 在赋值前被引用。

有人能解释一下为什么会这样吗?这是个错误还是一种特性?

第二个示例不是很有用,但我不明白为什么它不应该工作。我本以为函数 b 会先打印全局变量 a,然后检查全局变量 a 是否为 1。如果是这样,本地变量 a 会被设置为 2。然后根据全局变量 a 的值,可能会打印全局变量 a 或本地变量 a。在这个例子中,全局变量 a 是 1,所以我本以为会看到本地变量 a 打印出 2 的值。

示例 3:

a=1
def b():
    print a

工作正常

示例 4:

a=1
def b():
    print a
    a=2

失败了,示例 1 也失败了,正如评论中所说的,我其实只测试了示例 3,并认为它和示例 1 是一样的。

现在我明白了关于作用域的那些反复提到的事情。这对我来说完全是新鲜事,我对下面这个例子感到很有趣(Ipython):

In [13]: a=1

In [14]: def b():
   ....:     a=2
   ....:     global a
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
   ....:     print a
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
   ....:     
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<ipython-input-14-4fe1c6cdc9d0>:3: SyntaxWarning: name 'a' is assigned to before global     
declaration
  global a

In [15]: b()
2

In [16]: print a
2

所以这个机制和声明一个函数或类似的事情不同,在我改变状态之后才能访问它。

在 Python 中还有其他类似的操作吗?就像是穿越时间一样?

为了让这些示例正常工作,可以使用 globals():

示例 1 正常工作:

a=1
def b():
    print globals()["a"]
    a=2
    print a

示例 2 正常工作:

a=1
def b():
    global_a=globals()["a"]
    print global_a
    if global_a==1:
        a=2
    print a

示例 4 正常工作:

a=1
def b():
    print globals()["a"]
    a=2

相关问题: