当前位置:首页>python>Python 不可变类型作为函数参数传递特点

Python 不可变类型作为函数参数传递特点

  • 2026-09-22 10:08:15
Python 不可变类型作为函数参数传递特点

Python 函数传参本质是传引用(对象的内存地址),不存在“传值、传指针”,区分在于:不可变对象不能原地修改,可变对象可以原地修改。

不可变类型:int、float、str、bool、tuple、frozenset可变类型:list、dict、set

1. 核心特点

当把不可变对象传给函数:

  1. 函数内部拿到的是这个对象的内存地址引用;
  2. 不能修改原对象本身(对象内存里的数据不能改写);
  3. 如果函数内部对形参重新赋值,只是让局部变量指向新对象,完全不影响外部实参;
  4. 外部原始对象保持不变。

重点:不是“拷贝一份值传进去”,而是对象本身不可改写,赋值只会产生新对象。

2. 示例:int(不可变)

deffunc(num):
    print(f"函数内,修改前 id={id(num)}")
    num = 100# 重新赋值,num指向新int对象,局部变量
    print(f"函数内,修改后 id={id(num)}")

a = 10
print(f"外部实参 id={id(a)}")
func(a)
print(f"外部 a = {a}")

输出

外部实参 id=140xxxx
函数内,修改前 id=140xxxx
函数内,修改后 id=140yyyy
外部 a = 10
  • 刚进入函数:num 和外部a指向同一个对象;
  • num=100:不是修改原来整数,创建新整数对象,局部变量num指向新地址;
  • 外部变量a完全不受影响。

3. 字符串 str 示例(不可变)

字符串不支持原地修改,+=会生成新字符串

defchange_str(s):
    s += " world"# 生成新字符串对象,局部s指向新对象
    print("函数内部:", s)

s1 = "hello"
change_str(s1)
print("外部:", s1)

输出

函数内部: hello world
外部: hello

注意:s += xxx 对不可变类型,等价于 s = s + xxx,是重新赋值。

4. 元组 tuple

元组整体不可变,如果元组里面嵌套可变对象,嵌套的可变对象可以原地修改!这个是高频坑点。

t = (1, [2,3])

defchange_tuple(tp):
    tp[1].append(4)  # 没有修改元组本身,修改元组内部的list(可变)

change_tuple(t)
print(t)  # (1, [2, 3, 4])
  • tuple本身不可变,不能tp[0]=99;
  • 但元组只是存对象地址,如果里面装list/dict,list可以原地改动。

5. 和可变类型参数做对比(方便理解)

deffunc_list(lst):
    lst.append(99) # 原地修改对象,外部会跟着变

my_list = [1,2]
func_list(my_list)
print(my_list) # [1,2,99]

list是可变,append原地修改内存中对象,外部实参看到变化。

6. 总结表格

类型
传参进入函数
内部原地修改
内部重新赋值
外部实参变化
不可变(int/str/tuple)
共享对象地址
❌不允许原地修改
形参指向新对象
✅外部不变
可变(list/dict/set)
共享对象地址
✅原地修改原对象
形参指向新对象
原地改:外部变;重新赋值:外部不变

7. 面试一句话总结

Python全部参数传递都是传递对象引用。不可变类型作为参数,函数内部无法修改原始对象;函数内对形参赋值只会创建新对象,外部变量不受影响。如果元组内部嵌套可变对象,嵌套内容可以被原地修改。

最新文章

随机文章