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

Python中int与list的作用域差异原因解析

两段Python代码行为差异的底层原因解释

先看两段代码的实际运行表现:

代码1(触发错误)

# code 1
# makes an error

def func1():
    a += 1
a = 1

try:
    func1()
    print(a)
except UnboundLocalError as e:
    print(e)

运行后会输出:local variable 'a' referenced before assignment

代码2(正常执行)

# code 2
# makes no errors

def func2():
    b.append(1)
b = []
func2()
print(b)

运行后会输出:[1]

核心原因:变量作用域规则 + 可变/不可变对象的操作差异

  • Python的作用域判定逻辑:函数内部对变量的操作类型,直接决定了Python如何识别变量的作用域:

    1. 如果函数内存在对变量的赋值操作(包括+=这类语法糖,本质是重新赋值),Python会默认将该变量标记为局部变量,优先在函数局部作用域查找。
    2. 如果函数内只是调用变量指向对象的方法、修改对象内部数据(没有改变变量本身的指向),Python会去全局作用域查找该变量。
  • 针对两段代码的具体分析:

    • 代码1中,a += 1 等价于 a = a + 1,属于对变量a的赋值操作。Python编译func1时,会把a标记为局部变量,但函数内部并没有提前定义a,执行时尝试读取局部a的值来计算,就会触发UnboundLocalError。
    • 代码2中,b.append(1) 是调用列表对象的append方法,修改的是b指向的列表本身的内容,并没有改变变量b的指向(b依然指向原来的空列表)。Python不会把b标记为局部变量,会去全局作用域找到b对应的列表对象,执行修改操作,因此可以正常运行。
  • 可变/不可变对象的本质影响:
    这背后的差异也和Python对象的可变性直接相关:

    • a是不可变的int类型,要改变它的值只能通过重新赋值(让a指向新的int对象),这必然触发赋值操作,被判定为局部变量。
    • b是可变的list类型,修改列表内容不需要改变b的指向,只需要操作已有对象的内部数据,因此不会触发局部变量的判定。

内容的提问来源于stack exchange,提问作者심재승

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 22:37:53