You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python函数内操作局部变量为何会导致对应的全局列表被修改?

问题分析:Python列表赋值后意外修改原变量问题

测试代码

def test_func(a_global, b_global):
    a_local = a_global
    for i in range(len(a_local)):
        a_local[i] = i+1
    print("a_global: ", a_global)
    print("a_local: ", a_local)
    print()
    
    b_local = b_global
    c_local =[]
    for i in range(len(b_local)):
        c_local.append(i+1)
    b_local = c_local               #or b_local = [1,2,3,4,5]
    print("b_global: ", b_global)
    print("b_local: ", b_local)
    print()

    
a_global = [0,0,0,0,0]
b_global = [0,0,0,0,0]    

test_func(a_global, b_global)

运行输出

a_global:  [1, 2, 3, 4, 5]
a_local:  [1, 2, 3, 4, 5]

b_global:  [0, 0, 0, 0, 0]
b_local:  [1, 2, 3, 4, 5]

核心成因

这本质是Python可变对象的引用传递机制导致的,Python中所有变量赋值本质都是绑定对象的内存引用,不是复制对象本身:

  1. 第一个场景中,a_local = a_global 只是让局部变量a_local和全局变量a_global指向内存中的同一个列表对象。后续a_local[i] = i+1属于原地修改列表对象的操作,修改的是两个变量共同指向的内存数据,所以通过a_global访问时也能看到修改后的结果。
  2. 第二个场景中,最初b_local = b_global同样指向同一个列表,但后续b_local = c_local是给局部变量b_local重新绑定了一个新创建的列表对象,此时b_local已经不再指向原b_global对应的列表,后续操作都作用在新对象上,自然不会修改原全局变量。

可复用的规避方案

要避免传入的可变对象(列表、字典、自定义类实例等)被意外修改,核心是操作前先创建独立的对象拷贝:

  • 浅拷贝(适用于列表元素均为不可变对象,如数字、字符串、元组):
    可以用三种常用方式实现:
    • 调用列表自带的copy方法:a_local = a_global.copy()
    • 用切片语法快速拷贝:a_local = a_global[:]
    • 用list构造函数生成新列表:a_local = list(a_global)
  • 深拷贝(适用于嵌套可变对象的场景,如列表内嵌套列表、字典):
    需要导入标准库copy的deepcopy方法,会递归拷贝所有层级的对象:
    import copy
    a_local = copy.deepcopy(a_global)
    
  • 编码习惯优化:
    尽量避免在函数内部直接修改传入的可变参数,如果需要生成修改后的结果,建议将新结果作为返回值返回,由调用方决定是否覆盖原变量;同时减少全局可变变量的使用,尽量通过参数和返回值传递数据,降低代码副作用。

内容的提问来源于stack exchange,提问作者omeroguztemel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 03:36:04