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

为何move_rectangle函数会修改两个独立Rectangle对象的corner属性?

问题原因分析:浅拷贝导致内部可变对象共享

嘿,这个问题我之前写类的时候也踩过一模一样的坑!咱们来捋清楚为啥会出现两个Rectangle的corner同时被修改的情况~

核心问题出在浅拷贝(shallow copy)和深拷贝(deep copy)的区别上,尤其是当你的类里包含其他可变对象(比如这里的Point实例)的时候。

先还原一下你可能遇到的代码场景

假设你的move_rectangle方法大概是这么实现的:

def move_rectangle(rect, dx, dy):
    # 这里只做了Rectangle对象的浅拷贝,直接复用了原rect的corner
    new_rect = Rectangle(rect.corner, rect.width, rect.height)
    # 修改新矩形的corner坐标
    new_rect.corner.x += dx
    new_rect.corner.y += dy
    return new_rect

为什么两个对象的corner会同时变化?

当你创建new_rect的时候,你只是把原rect的corner属性直接传给了新的Rectangle实例——这意味着new_rect.corner和box.corner指向的是同一个Point对象!

Rectangle本身是新创建的,但它内部的corner是对原Point实例的引用,并没有生成一个新的Point。所以当你修改new_rect.corner.x的时候,本质上是在修改那个共享的Point对象的属性,自然原box的corner也会跟着变。

怎么修复这个问题?

要实现真正的深拷贝,你需要确保内部的可变对象也被复制一份:

  1. 手动创建新的Point实例
    在生成新Rectangle的时候,不要直接传原corner,而是基于原Point的坐标创建一个新的Point:

    def move_rectangle(rect, dx, dy):
        # 创建新的Point对象,复制原corner的坐标
        new_corner = Point(rect.corner.x, rect.corner.y)
        new_rect = Rectangle(new_corner, rect.width, rect.height)
        new_rect.corner.x += dx
        new_rect.corner.y += dy
        return new_rect
    
  2. 使用copy模块的deepcopy函数
    如果你的类结构更复杂,手动复制每个内部对象太麻烦,可以用Python内置的copy.deepcopy,它会递归地复制所有嵌套的可变对象:

    import copy
    
    def move_rectangle(rect, dx, dy):
        # 深拷贝整个Rectangle对象,包括内部的Point
        new_rect = copy.deepcopy(rect)
        new_rect.corner.x += dx
        new_rect.corner.y += dy
        return new_rect
    

总结一下:当你需要复制包含可变对象的自定义类时,浅拷贝只会复制外层对象的引用,内部的可变对象还是共享的;只有深拷贝才能彻底复制所有嵌套的对象,让新实例和原实例完全独立。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 07:53:12