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

对象副本修改引发原对象突变?含DataFrame属性类的不可变实现求助

How to Keep Original Class Object Immutable During Arithmetic Operations with DataFrame Attributes

Got it, let's break this down clearly—you're hitting a classic reference vs. true copy problem here, and pandas DataFrames add a little extra complexity with their shallow vs. deep copy behavior. Let's walk through why your current approach isn't working, then fix it.

Why copy = self Fails

First off, copy = self doesn't create a new object—it just creates a new variable that points to the exact same instance as self. Any changes you make to copy will directly modify the original object because they're the same thing under the hood. That's why your original object is getting altered.

Why Even df.copy() Might Not Be Enough

Pandas' df.copy() method defaults to a shallow copy (deep=False). If your DataFrame contains mutable objects like lists, dictionaries, or other nested DataFrames, a shallow copy will still share those internal objects with the original. So modifying those nested elements in the copied DataFrame would still change the original.

The Fix: Create a New Instance with Deep Copied Data

To keep your original object immutable, you need to:

  1. Create a brand new instance of your class, not just a reference to the original.
  2. Deep copy the DataFrame attribute (and any other mutable attributes) to ensure the new instance has completely independent data.

Here's a concrete example:

import pandas as pd
import copy

class DataHolder:
    def __init__(self, df):
        # Store the DataFrame (we'll handle copying in operations)
        self.df = df

    # Example: Implement the addition operator
    def __add__(self, other):
        # 1. Deep copy the original DataFrame to avoid modifying it
        new_df = self.df.copy(deep=True)
        # 2. Perform the arithmetic operation on the copied DataFrame
        new_df += other.df
        # 3. Return a NEW instance of DataHolder with the modified DataFrame
        return DataHolder(new_df)

    # Repeat this pattern for other operators (__sub__, __mul__, etc.)

Test It Out

# Create original objects
original_df = pd.DataFrame({"value": [1, 2, 3]})
obj1 = DataHolder(original_df)
obj2 = DataHolder(pd.DataFrame({"value": [10, 20, 30]}))

# Perform addition—this returns a NEW object
result_obj = obj1 + obj2

# Check original is unchanged
print("Original DataFrame:")
print(obj1.df)  # Still shows [1,2,3]

# Check result is correct
print("\nResult DataFrame:")
print(result_obj.df)  # Shows [11,22,33]

Key Takeaways

  • Never use copy = self—it's just a reference, not a new object.
  • Always use df.copy(deep=True) for pandas DataFrames when you need full independence (or copy.deepcopy(self.df) for even more nested cases).
  • Arithmetic operator methods (like __add__, __mul__) should return a new instance of your class, not modify self in place. This ensures immutability by design.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:12:52