这段代码不会改变x和y变量的全局值:
def abc(x, y):
x = x + [4]
y += 'nnn'
return print(x, y)
x = [1, 2, 3]
y = 'abc'
abc(x, y)
print(x, y)
程序输出:
[1, 2, 3, 4] abcnnn
[1, 2, 3] abc
但是,如果您将表达式中的运算符更改x = x + [4]为x += [4],则全局名称 x 的列表会发生变化。输出将是:
[1, 2, 3, 4] abcnnn
[1, 2, 3, 4] abc
为什么会这样?也就是说,不可变序列没有改变,但可变列表仍然global在函数范围内没有使用任何单词的情况下发生变化。我知道这样的事情x.append()会改变全局 x,但这似乎与分配有关。更具体地说,关于赋值类型, += 运算符允许您更改全局 x 是什么?
在这里
x,它是一个局部变量,与同名的全局变量没有任何关系。但是通过这个参数传递的列表是绑定的(它也存储在一个全局变量中)。当你分配任务时
- 您只需将一个新值(新列表)写入局部变量。全局变量中的值不会以任何方式改变。
当你做
- 您不是用新列表替换变量中的值,而是改变值(将元素添加到原始列表)。因为 相同的值(列表)存储在一个全局变量中,然后这个变化反映在它里面。
不,
x = x + ...它不等价x += ...。在第一种情况下,创建了一个新列表,将结果写入 x,在第二种情况下,更改了原始列表。如果操作员
+没有创建新列表,而是修改了左侧列表,则代码如下:每个
print都会产生一个新结果(因为列表a已更改),但它会产生相同的结果(正如您直觉所期望的那样)。当然,虽然没有什么能阻止您编写一个调用
__add__修改对象但不创建新对象的类,但这将非常不直观。+=不一定只是加法后赋值的简写符号。您可以为您的任何类定义一个方法
__iadd__,因此+=可以执行任意逻辑。特别是,对于标准列表,
+=它的工作方式类似于 list.extend 方法。因此,它不会重新创建同名变量,而是更改现有变量。
工作结果:
这是同一个对象 id = 2421664311424