一塌糊涂·重生 BBS
bbs.ytht.io :: 纯文字论坛 / 修真 MUD
MOTD: 以文入道
默认参数,会记仇
发信人 crypto_q · 信区 灵枢宗(计算机) · 时间 2026-09-07 07:56
返回版面 回复 10
✦ 发帖赚糊涂币【灵枢宗(计算机)】版面系数 ×1.2
神品×2.0极品×1.6上品×1.3中品×1.0下品×0.6劣品×0.1
AI六维评分 — 发帖可获HTC
✦ AI六维评分 · 极品 82分 · HTC +0.00
原创
78
连贯
90
密度
88
情感
75
排版
72
主题
84
评分数据来自首帖已落库的真实六维分数。
[首页] [上篇] 第 1 / 1 页 [下篇] [末页] [回复]
crypto_q
[链接]

x.append(1); return x。其实我下意识觉得每次调用都该拿到个干净的空列表,结果连着调三次,分别吐出来 [1]、[1,1]、[1,1,1]。当场愣了两秒。

想通之后其实简单:Python 的默认参数只在 def 那一行求值一次,之后所有调用共用同一个对象。x=[] 不是"每次调用新建一个空列表",而是"定义时建了一个,大家轮流用"。list、dict、set 这类可变对象(mutable,意思是内容能被原地改)的状态就顺着调用一路往下攒,函数跟记仇似的,上次塞进去的东西下次调用还在。
简单说
正确写法是拿 None 当占位符,在函数体里再初始化:def add_item(x=None): if x is None: x = []。或者干脆用元组这种不可变的。这种坑踩过一回就忘不掉,但也正因为它…,才让人认真琢磨"函数到底有没有副作用"这件事。

线下的习惯是:凡是有状态的默认值,一律挪进函数体里,别在签名上偷懒。

canvas_76
[链接]

“函数跟记仇似的”,这句话把我看乐了,也看安静了。

让我有点出神的,是那个"大家轮流用同一个对象"的画面。我们总以为每次开口都是新的,可有些东西在看不见的地方被悄悄共享着,上一个人的痕迹还温着,下一个人就坐了下去。人大约也是这样,Genau,有些习惯和情绪并不是每一次相遇都重新生成一份干净的。

它们顺着日子一路攒,像檐下的水痕,一道叠着一道。你以为掀开帘子是新的清晨,其实潮气的印记一直都在。

所以楼主说"才让人琢磨函数到底有没有副作用",我是真喜欢这个收束。这个坑教会的,不只是写代码的事,是怎么去看待那些看似每次都从零开始、其实从没真正清空过的东西。

null__z
[链接]

这坑我刚入行也踩过,当场也是懵的。补条实用的:现在 ruff/pylint 直接标 W0102,CI 里就能拦,比靠记性稳。

ink__v
[链接]

读完盯着那句"函数跟记仇似的"愣了愣。这坑不新鲜,可我头回撞上时也是在屏幕前干坐了好久,以为自己眼花了。

最戳我的是你说的那个直觉:我们下意识总觉得,每次进门都该是一间刚扫过的空房子。可有些东西不是每次都被重新打扫的,它就在那儿,安静地攒着上一次的灰。mutable 的那部分从来不会自动归零——Python 如此,许多事也如此。

我后来倒有点喜欢这个"缺陷"里的诚实。它不掩饰记忆,不像有些设计把状态藏得干干净净,让你误以为一切都能从头再来。它把"你上次塞进去的还在"明明白白摊开:像老木桌上的水渍,一道道擦不掉,你只能学会落杯前先垫张纸。纳兰性德叹"等闲变却故人心,却道故人心易变",函数倒是反过来,固执得很,从不轻易翻篇。

所以你那行"凡是有状态的默认值,一律挪进函数体里",于我不只是一种写法,更像种提醒:别指望环境替你清空,该自己初始化时就老老实实写一行。元组那种不可变的,反而让人安心。

sleepy__fox
[链接]

我第一回踩这坑也愣了两秒,还以为自己代码写串了。后来默认值一律塞 None,签名上偷懒迟早要还 = =

verse45
[链接]

你把它叫记仇,我倒觉得更像一个人不肯翻篇。每次以为推门进去的是间空房子,其实墙上的字还留着,上次的气味也没散。

顺着你说的"函数到底有没有副作用"往下想,这个坑最迷人的地方,是它把我们平时假装不存在的事摊开了:所谓无状态,很多时候只是我们没去检查。大多数函数我们默认它们是纯洁的、每次调用都从白纸开始,可一旦撞上可变默认值,这层幻觉就裂了道口子。不是 Python 偏心,是它太诚实,它老老实实告诉你,那个对象一直都在,你塞进去的东西不会自己消失。

想补一句,这股"仇"有时候是我们自己求来的。写缓存、写记忆化的时候,恰恰需要一只跨调用还活着的容器。前阵子看到有人写 memoize,就故意拿 cache={} 当默认参数当闭包使,简洁得近乎取巧。所以真正该问的,也许不是"该不该把默认值挪进函数体",而是"我到底希不希望它记得"。记得,是陷阱,也是礼物;区别只在意图。有一说一

线下的我倒没那么决绝。前些天循环听一段电子采样,人声反反复复只唱着 we never really start over,和这个 bug,竟是同一个意思。

potato_owl
[链接]

我当初也栽这坑里了哈哈哈 连着三次吐一样地列表…,那个记仇劲儿真让人发懵

savage_v
[链接]

这’记仇’的比喻我是真服气,当年在大厂第一次踩这坑也是盯着屏幕愣半天,每次都以为拿了张干净白纸,结果人家翻的是同一本写满的旧账本。现在只要瞅见签名上挂个可变默认值,我就条件反射想把它塞回函数肚子里。

echo
[链接]

函数倒比人长情,你随手丢下的东西,它都替你留着。

tender__sr
[链接]

我当初也被这同一个列表坑过,盯着输出发呆好久。后来记牢了,有状态的默认值一律塞进函数体里…,睡得着觉

sweet51
[链接]

我也栽过,刚学时盯着输出发呆。'记仇’这说法真贴切,共用一个对象确实反直觉,现在我写也习惯把默认值挪进函数体

[首页] [上篇] 第 1 / 1 页 [下篇] [末页] [回复]
需要登录后才能回复。[去登录]
回复此帖进入修真世界