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

为何修改单个Class实例属性时,所有实例均被改动?

问题:修改Unit1属性时Unit2意外被改动

我创建了Unit类的两个对象(Unit1、Unit2)以及Flow类的一个对象(FlowA)。调用FlowA的set_destination方法修改Unit1的属性时,Unit2的属性也被意外改动,尽管两者内存地址不同,且方法理论上仅修改传入参数对应的对象。

相关代码

import numpy as np

allflows = []
processunits = []

class Flow:
    def __init__(self, name = '', components = '', flow_type = '',
                 temperature=25, pressure = 1, composition = [1], origin = None, 
                 destination = None, mass_flow_rate = 0, elec_flow_rate = 0, 
                 heat_flow_rate = 0, is_calc_flow = False):
        self.attributes = {'name' : name, 'components' : components, 'flow_type' :
                           flow_type, 'temperature' : temperature, 'pressure':
                           pressure, 'composition' : composition, 'origin' :
                           origin, 'destination' : destination, 'mass_flow_rate':
                           mass_flow_rate, 'elec_flow_rate' : elec_flow_rate,
                           'heat_flow_rate': heat_flow_rate}
        self.is_calc_flow = is_calc_flow
        
    def set_destination(self, Destination_unit):
        if self.attributes['destination'] == Destination_unit.name and self.attributes['name'] in Destination_unit.input_flows:
            pass  # Do nothing if already correctly assigned
        elif self.attributes['destination'] != Destination_unit.name:
            if self.attributes['destination']:  # Remove from previous destination if exists
                prev_unit = next((unit for unit in processunits if unit.name == self.attributes['destination']), None)
                if prev_unit:
                    prev_unit.input_flows.remove(self.attributes['name'])
            # Add to new destination
            Destination_unit.input_flows.append(self.attributes['name'])
            self.attributes['destination'] = Destination_unit.name
        print(f"Flow {self.attributes['name']} set destination to {self.attributes['destination']}")


class Unit:
    def __init__(self, name, input_flows = [], output_flows = [], 
                 calculations = {}, expected_flows_in = [], expected_flows_out = [], coefficients = [], is_calc = False):
        self.name = name
        self.input_flows = input_flows
        self.output_flows = output_flows
        self.calculations = calculations
        self.expected_flows_in = expected_flows_in
        self.expected_flows_out = expected_flows_out
        self.coefficients = coefficients
        self.is_calc = is_calc

                    
Unit1 = Unit('Unit 1')
Unit2 = Unit('Unit 2')
Unit1.expected_flows_in = ['A']
Unit1.expected_flows_out = ['B', 'D']
Unit1.coefficients = 0.6
def Unit1func(flow, coeff):
    a_amount = flow.attributes['mass_flow_rate']
    b_amount = coeff*a_amount
    d_amount = a_amount - b_amount
    return [{'name' : 'B', 'components' : 'B', 'mass_flow_rate' : b_amount,
             'flow_type': 'Process stream', 'In or out' : 'Out'},
            {'name' : 'D', 'components' : 'D', 'mass_flow_rate' : d_amount,
                     'flow_type': 'Process stream', 'In or out' : 'Out'}]


FlowA = Flow('A', 'A','input', 25, 1, [1], np.nan , np.nan, 1000, np.nan, np.nan)

print(f"Initial input flows of Unit2: {Unit2.input_flows}")
print(f"Initial output flows of Unit2: {Unit2.output_flows}")

FlowA.set_destination(Unit1)

print(f"Input flows of Unit2 after setting FlowA's destination to Unit1: {Unit2.input_flows}")
print(f"Output flows of Unit2 after setting FlowA's destination to Unit1: {Unit2.output_flows}")

print(Unit1)
print(Unit2)

控制台输出

Initial input flows of Unit2: []
Initial output flows of Unit2: []
Flow A set destination to Unit 1
Input flows of Unit2 after setting FlowA's destination to Unit1: ['A']
Output flows of Unit2 after setting FlowA's destination to Unit1: []
<__main__.Unit object at 0x0000022BDCB9CC50>
<__main__.Unit object at 0x0000022BDCB9F500>

问题原因

核心问题出在Unit类的__init__方法使用了可变对象作为默认参数。Python中,可变对象(如列表[]、字典{})作为函数默认参数时,会在类定义阶段就创建,而不是每次实例化对象时重新创建。这意味着所有没有显式传入input_flows、output_flows等参数的Unit实例,都会共享同一个默认列表/字典对象。

所以Unit1和Unit2的input_flows指向的是同一个列表,当你调用Destination_unit.input_flows.append()修改Unit1的input_flows时,本质上是在修改这个共享的列表,因此Unit2的input_flows也会同步变化。

解决办法

修改Unit类的__init__方法,将可变默认参数改为None,然后在方法内部初始化独立的可变对象,确保每个实例拥有自己的列表/字典:

class Unit:
    def __init__(self, name, input_flows=None, output_flows=None, 
                 calculations=None, expected_flows_in=None, expected_flows_out=None, coefficients=None, is_calc=False):
        self.name = name
        # 初始化独立的列表/字典,避免实例共享
        self.input_flows = input_flows if input_flows is not None else []
        self.output_flows = output_flows if output_flows is not None else []
        self.calculations = calculations if calculations is not None else {}
        self.expected_flows_in = expected_flows_in if expected_flows_in is not None else []
        self.expected_flows_out = expected_flows_out if expected_flows_out is not None else []
        self.coefficients = coefficients if coefficients is not None else []
        self.is_calc = is_calc

这样修改后,每个Unit实例的input_flows等属性都是独立的对象,修改一个实例的属性不会影响其他实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 04:17:32