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

Python中函数内修改类实例为何无法同步到调用函数作用域

Python参数传递机制说明

Python不存在传统编程语言里的“按值传递”或“按引用传递”,采用的是**传对象引用(又称传赋值)**机制:调用函数时,会把外部传入的对象的内存地址,绑定到函数内部的形参变量上。形参和外部实参最初指向同一个对象,但对形参变量本身的重新赋值,不会对外部作用域的实参产生任何影响。

两类操作的效果差异

你遇到的问题本质是混淆了「修改对象本身」和「给形参变量重新赋值」的区别:

  • 如果操作是修改对象的属性、修改可变对象内部的元素(比如给list追加元素、修改ListNode实例的next属性):因为形参和实参指向内存里的同一个对象,这类修改会同步反映到外部作用域。
  • 如果操作是给形参变量直接赋值(比如你写的l = l.next、res = res.next):本质只是修改函数内部局部变量的指向,让这个局部变量从原来指向的对象,改成指向另一个对象,这个改动完全不会触碰外部作用域的变量。

你的代码里,外部while循环的判断条件依赖ll的指向,但你在函数内部对形参l做l = l.next的赋值,根本不会改变外部ll的指向,ll永远指向链表的第一个节点,循环条件永远为真,自然会陷入无限循环。
除此之外你代码里还有一个完全同源的bug:函数内的res = res.next同样不会改变外部res变量的指向,就算循环能终止,你得到的复制链表也只有一个节点,根本无法形成完整的链式结构。

修复方案

不要尝试在被调用函数内部通过给形参重新赋值的方式,移动外部作用域的遍历指针,两种可行的实现方式:

  1. 把遍历指针的移动逻辑放在同一个作用域内实现,示例代码:
class ListNode:
     def __init__(self, val=0, next=None):
         self.val = val
         self.next = next

# 构建原链表
ll = ListNode(1)
ll.next = ListNode(2)

def copy_linked_list(origin_head):
    dummy = ListNode()
    cur_res = dummy
    cur_origin = origin_head
    while cur_origin:
        cur_res.next = ListNode(cur_origin.val)
        cur_res = cur_res.next
        cur_origin = cur_origin.next
    return dummy.next

new_ll = copy_linked_list(ll)
  1. 如果必须拆分为独立的单步处理函数,让函数返回更新后的指针位置,在外部作用域接收返回值完成指针移动:
def append_new_node(res_cur, origin_cur):
    res_cur.next = ListNode(origin_cur.val)
    return res_cur.next, origin_cur.next

res_dummy = ListNode()
res_cur = res_dummy
cur_origin = ll
while cur_origin:
    res_cur, cur_origin = append_new_node(res_cur, cur_origin)
new_ll = res_dummy.next

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 20:15:52