【问题标题】:Scope of lists in Python 3Python 3 中的列表范围
【发布时间】:2015-03-02 21:06:32
【问题描述】:

这可能是一个非常愚蠢的问题,但我有点不确定为什么列表在范围方面与 Python 3 中的其他变量不同。在下面的代码中...

foo = 1
bar = [1,2,3,4]

def baz():
    foo += 1
    bar[0]+=1

我理解为什么foo += 1 会抛出关于foo 超出本地范围的错误。为什么bar[0]+=1 不抛出同样的错误呢?

【问题讨论】:

  • 因为bar[0] 是一个读取bar 的表达式,这在python 中是允许的。

标签: python list scope


【解决方案1】:

当你执行代码时,你会得到

 ....
     foo += 1
 UnboundLocalError: local variable 'foo' referenced before assignment

foo += 1 实际上是这样评估的。 foo = foo + 1。因此,您将1 添加到foo 的值中,并将其存储在变量foo 中。由于发生了赋值,Python 假定 foo 是一个局部变量。但是,如果它是一个局部变量,在表达式foo + 1 中,foo 的值是多少? Python 无法回答这个问题。这就是它抛出该错误的原因。

但是,当您执行 bar[0] += 1 时,Python 会像 bar[0] = bar[0] + 1 一样评估它。因为,它已经知道bar 是什么,而您只是试图替换其中的第一个元素,它允许它。在最后一种情况下,我们通过执行foo += 1 创建了一个名为foo 的新局部变量,但在这里,我们只是更改了同一个对象。所以 Python 允许这样做。

【讨论】:

    【解决方案2】:

    变量foo 指向一个对象(一个整数)。变量baz 指向一个对象(一个列表)。如果您尝试将 baz 重新分配给另一个对象,您会收到错误消息。但你不是,你只是在列表对象上调用一个方法,任何人都可以这样做。

    【讨论】:

      【解决方案3】:

      在 python 中,如果没有 'global' 关键字,您将无法修改全局变量。这是为了清楚起见。

      foo=1
      def bar():
           global foo
           foo=2
      bar()
      #foo is now 2!
      

      由于 bar[0]+=foo 修改的是列表的 an 元素,而不是列表变量本身的值,所以是合法的。

      【讨论】:

        猜你喜欢
        • 2016-12-28
        • 2012-07-13
        • 1970-01-01
        • 1970-01-01
        • 2016-02-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-11
        相关资源
        最近更新 更多