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

Python方法默认参数results=[]为何复用?是否为官方行为?

Python 可变默认参数的状态共享问题

版本信息

版本:Python 3.10.6 (main, Nov 14 2022, 16:10:14) [GCC 11.3.0]

代码示例

from dataclasses import dataclass

class _Mixin:
    def vars_to_dct(self, results=[]):
        dct = self.to_dict()
        for k in dct.keys():
            results.append(k)
        return results


@dataclass
class ClassA(_Mixin):
    a: str = ""
    b: str = ""


@dataclass
class ClassB(_Mixin):
    c: str = ""
    d: str = ""
    e: str = ""

测试结果

单独调用(符合预期)

a = ClassA()
assert ["a", "b"] == a.vars_to_dct()
b = ClassB()
assert ["c", "d", "e"] == b.vars_to_dct()

连续调用(触发异常)

a = ClassA()
assert ["a", "b"] == a.vars_to_dct()

b = ClassB()
assert ["c", "d", "e"] == b.vars_to_dct()  # 抛出AssertionError

实际返回结果:

b = ClassB()
assert ["a", "b", "c", "d", "e"] == b.vars_to_dct()

显式传入参数(符合预期)

b = ClassB()
assert ["c", "d", "e"] == b.vars_to_dct(results=[])

问题解析

这是Python可变默认参数的经典陷阱,和类变量/静态成员无关,核心逻辑如下:

  • Python函数的默认参数仅在函数定义阶段初始化一次,而非每次调用时重新创建。像列表这类可变对象,初始化后会作为函数的固定属性存在,所有未显式传入参数的调用,都会复用同一个对象。
  • 可以通过print(_Mixin.vars_to_dct.__defaults__)验证:默认的results列表始终是同一个对象,每次调用append都会往该列表中添加元素,导致跨调用的状态残留。

修复方案

将默认参数设为None,在函数内部初始化新列表,确保每次调用都使用独立的列表对象:

class _Mixin:
    def vars_to_dct(self, results=None):
        if results is None:
            results = []
        dct = self.to_dict()
        for k in dct.keys():
            results.append(k)
        return results

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 06:45:37