首页 > 解决方案 > 变量范围(局部全局和非局部)如何适用于 Python 中的 List 等可变对象?

问题描述

我正在编写如下程序来测试我对 Python 变量范围的了解

def show(a,b):
    def add():
        a = a+b #Error at this line "UnboundLocalError: local variable 'a' referenced before assignment" 
#I know we can use nonlocal a,b to avoid error 
    add()
    print("a=",a)
x=4
y=2
show(x,y)

然后我尝试了相同的程序,其中 x 和 y 作为列表进行了一些小改动。代码如下图

def show(a,b):
    def add():
        a[0] = a[0]+b[0] #No Error at this line
    add()
    print("a=",a[0])

x=[4]
y=[2]
show(x,y)

这段代码运行良好。我在 python 中没有得到这种奇怪的行为。

标签: python

解决方案


所有变量的范围规则都是相同的。它们指的是什么对象并不重要。

但是,a = a + ba[0] = a[0] + b[0]是不同的东西。

  1. 第一个是分配给一个全局变量,它实际上被 Python视为本地变量。详细信息可以在这篇文章中找到:Python 函数全局变量?

  2. 第二个是语法糖,做作业!它被脱糖(内部翻译)调用__setitem__

    a.__setitem__(0, a[0] + b[0])
    

    如您所见,这里没有分配,上面的第 (1) 点不适用,所以这里没有问题。

一般来说,代码 likea[i] = b会被翻译成a.__setitem__(i, b),而其他一些语法也会被翻译成函数调用,比如a + bcan be a.__add__(b)a[0]isa.__getitem__(0)等等。

所以,a[0] = a[0] + b[0]最终将成为这个怪物:

a.__setitem__(0, a.__getitem__(0).__add__(b.__getitem__(0)))

没有赋值 - 全局变量突然变成本地没有问题。


推荐阅读