360 Secure SkillHub
360 安全技能中心

Python Mutable Default Args

该 Skill 是一份关于 Python 可变默认参数(list、dict、set)的说明文档,讲解默认值只在函数定义时求值一次、从而在多次调用间共享状态并产生静默 Bug 的原因,列出典型症状,并给出用 None 作为默认值、在函数体内初始化的标准修复方式,同时提到可借助 pylint W0102 和 ruff B006 自动发现该模式。

mvogt99
mvogt99
热度 32.61
最近更新 2026-05-11 17:46:25
分类:开发依赖:纯提示词应用场景:调试排错 / 代码审查 / 概念解释

安装技能

复制下面的话术发给你的 Agent,它会通过 secure-skills 检索并安装该技能。

执行命令安装此 skill: npx secure-skills-cli add python-mutable-default-args
Metadata
name
python-mutable-default-args
description
A Python function uses a mutable object (list, dict, set) as a default argument, sharing state across calls in a way that produces silent bugs.
emoji
🐍
metadata
{"clawdis":{"os":["macos","linux","windows"],"language":"python"}}

python-mutable-default-args

Python evaluates default argument values once at function definition time, not on each call. If the default is a mutable object — a list, dict, or set — that object is shared across every call that uses the default. Mutating it inside the function modifies the default for all future calls. The bug is invisible until the second or later call and produces state-dependent failures that are hard to trace.

Symptoms

def add_item(item, items=[]):   # ← shared list
    items.append(item)
    return items

add_item("a")  # ["a"]
add_item("b")  # ["a", "b"]  ← unexpected; second caller sees first caller's data
  • A function that accumulates data into a list or dict default grows unboundedly across calls.
  • A function that should be stateless produces different results on the second call than the first.
  • Unit tests pass in isolation but fail when run together due to shared state from a prior test.
  • The bug disappears if the function is called with an explicit argument.

What to do

  • Use None as the default and initialize the mutable inside the function body:

    def add_item(item, items=None):
        if items is None:
            items = []
        items.append(item)
        return items
    
  • This is the canonical Python idiom. Every call that omits items gets a fresh list.

  • Applies equally to dict, set, and any other mutable type. The rule is: never use a mutable as a default argument.

  • When reviewing code, scan every function signature for =[], ={}, =set() as a heuristic for this pattern.

  • Linters (pylint rule W0102, ruff rule B006) will flag this automatically — enable them if the codebase doesn't already.