首页 注册 登录
V2EX = way to explore V2EX 是一个关于分享和探索的地方
现在注册 已注册用户请 登录
V2EX Python

吐槽 Python 的 *args, **kwargs

justdoit123 · 2024 年 10 月 10 日 · 5139 次点击
这是一个创建于 457 天前的主题,其中的信息可能已经有所发展或是发生改变。
接手一个数据拷贝的任务,在老代码里看到大量 def xxx_fn(*args, **kwargs) 真的血压升高。

这两兄弟里面"什么都有,又什么都没有",反正全靠猜。

没有注释,就算有注释,随时时间迁移也未必准确。

从最外层到最内层,每一层都有可能往 kwargs 里塞参数或者 pop 参数。

这样的代码心智负担大,理解起来效率低。

这种写法一点也不酷,真的要慎重是用。另外要吐槽,python 社区还有大量这种库(包括官方自带的库),不过幸好质量好一点库都有参数注释,而且(应该是)有持续维护。


我也在思考,为什么各类语言要有那么多酷炫无比的特性?我认为,这些特性大部分是为基础库服务的。上层逻辑代码乱用这种特性,只会给自己找麻烦。


一下省略 "*args, **kwargs" 个字
49 条回复 2024年10月17日 10:42:49 +08:00
ipwx
1
ipwx 2024 年 10 月 10 日
因为好的库不用这个,反而 Annotation 用的多。
justdoit123
2
justdoit123
OP
2024 年 10 月 10 日
麻蛋,看这种代码感觉自己是在 剥洋葱/捉迷藏。

十年前的 coder 说:"大王,来抓我呀〜 " "我在这,来抓我呀〜"。
summerwar
3
summerwar 2024 年 10 月 10 日 ❤️ 1
基础性的方法不限制传入的参数的数量和种类,可以更方便的处理各种数据,十分灵活。如果你要限定传入的参数和内容,那么可以在基础方法的基础上再定义函数和具体化参数。

*args 表示传入的是列表或元祖,*kwargs 传递的是字典,记住这两条就问题不大了,按照这个规则将获取到的参数放入自己的方法里,不在自己方法里的参数直接丢掉就好了。
mark2025
4
mark2025 2024 年 10 月 10 日
动态一时爽,维护 xxx 。 动态还是 TS 最爽,兼顾 js 的灵活以及类型保护
shylockhg
5
shylockhg 2024 年 10 月 10 日
这玩意我只记得以前弄懂过一次,现在又忘完了
iorilu
6
iorilu 2024 年 10 月 10 日
python 确实很多地方用这个, 其实主要就是为了兼容未来可能增加得参数, 这样以后
随便传啥, 反正接口不用改
ounxnpz
7
ounxnpz 2024 年 10 月 10 日
如果你想写个通用一点的装饰器,没这两个还真的不方便。这两个参数用于传递很好用,不要滥用就好
yohole
8
yohole 2024 年 10 月 10 日 ❤️ 2
这是 javaer 学 python 最难受的一点
git00ll
9
git00ll 2024 年 10 月 10 日
是的很难受,特别是调用第三方接口时,压根不知道往里面传什么
iorilu
10
iorilu 2024 年 10 月 10 日
@ounxnpz 是的, 装饰器必须用这个兼容所有接口得

所以说, python 很多所谓技巧, 其实不是技巧, 而是刚需

你可以不用, 但你必须知道
Binwalker
11
Binwalker 2024 年 10 月 10 日
ruby 里面也有,而且比这个还自由
fatigue
12
fatigue 2024 年 10 月 10 日 ❤️ 1
工程设计的锅东西别让语言特性来背
Jinnrry
13
Jinnrry 2024 年 10 月 10 日 ❤️ 5
和语言没啥关系,和人有关系。
难道 php 就不能一个 array 满天飞了吗?
难道 java 就不能一个 Object 满天飞了吗?
难道 golang 就不能一个 any 满天飞了吗?


不过有一说一,接手 python 代码我是最害怕的,1 个项目 10 个人有 100 种写法,每次都能学到新姿势。python 天天喊着"人生苦短",就这 100 种写法,看下来确实人生苦短了
TimG
14
TimG 2024 年 10 月 10 日 via Android
@Jinnrry 不能这么说,还是跟语言有关系的,python 显然有支持这种行为的意图,现在都成为一种标准了。Java 要是装箱不用拆我也用,但它是强类型,不光写一堆拆箱还要折算性能损耗,合计下来就很不经济。
AV1
15
AV1 2024 年 10 月 10 日
有类型标注还好,如果没类型标注,维护 python 就是痛苦的折磨
14
16
14 2024 年 10 月 10 日
同感,我最近喜欢 def func(*, a, b=2, c) 这样定义,这样调用的时候必须 func(a=1, c=3) 强制写清楚参数名字,并且 abc 可以在任意位置写默认值
buf1024
17
buf1024 2024 年 10 月 10 日 ❤️ 2
防御性编程,值得点赞。
ClericPy
18
ClericPy 2024 年 10 月 10 日
老代码让我用 type-hints 给包了一层 interface 。。。

不敢动底层啊,上次动了,加班到晚上 9 点多!
est
19
est 2024 年 10 月 10 日
数据拷贝任务你换啥语言来都是 dirty work
bhy
20
bhy 2024 年 10 月 10 日
可以试试看 pytype 能不能 infer kwargs 的类型。看了一圈,mypy 和 pyright 应该还不支持。
miaotaizi
21
miaotaizi 2024 年 10 月 10 日
"屎中一坨", 别说什么 "人生苦短", 不接受反驳
NoOneNoBody
22
NoOneNoBody 2024 年 10 月 10 日
params = ((1,2,3), (4,5,6,7), ...)
result = 0
for i,fun in enumerate((fun1, fun2, fun3, ...)): result=fun(result, *params[i])
print(result)

有些时候,上述 1,2,3 或 4,5,6,7 这些参数就是从上游得到的结果,只需按需顺列好传到下游计算,不需要理会其具体意义,这时候,args 就很有用了
例如上述代码写成闭包,只需传 params 和 result 初始值,就能完成一长串的计算,不需要记太多参数意义,可能更重要的点是 fun1/fun2/fun3...的顺序

数据预处理、标准化经常就是这样枯燥的,步骤和参数固定,机械化按顺序执行就是了
爬虫也是,无非就是 bs4+selector ,re+pattern ,lxml+xpath ,函数形式基本固定,变化只是 selector/pattern/xpath 这些,bs4/re/lxml 谁先谁后可能更重要

其实还有其他用法,如参数"补齐"
有十个参数,参数名都是固定的,有若干个 fun 都用这些同名参数,fun1 只用到 3 个,fun2 只用到 7 个......,可以全部十个都用 kwargs 传进去,传多了也不会错,不用逐个 fun 检查并选择哪些参数。例如处理图片,很多函数都是用相同的参数名,其意义也固定的,什么宽高、通道数......如果已知足够多参数,一起用 kwargs 传过去也不会错的,除非这个用 w/h 表示宽高,那个用 width/height 表示宽高,这就麻烦了
miaotaizi
23
miaotaizi 2024 年 10 月 10 日
@NoOneNoBody 为什么不把你的 10 个参数 做成一个对象?
300
24
300 2024 年 10 月 10 日
更难受的是查找调用,结果弹出几十个无关路径,仅仅因为名字一样==
NoOneNoBody
25
NoOneNoBody 2024 年 10 月 10 日
@miaotaizi #23
也可以啊,dataclass 就是这个用途吧,只是我没参透

def fun1(width, height): ...
def fun2(a, width,height): ...

params = {'width': 1920, 'height':1080}

fun1(**params)
a = 123
fun2(a, **params)
R4rvZ6agNVWr56V0
26
R4rvZ6agNVWr56V0 2024 年 10 月 10 日
语法糖能取代 BOB 大爷的设计模式吗 LMAO
至今为止尚未有语言可以做到吧。所以也别吐槽灵活性设计了。
justdoit123
27
justdoit123
OP
2024 年 10 月 10 日
没有攻击语言的意思。 估计这也是工程演进的产物。

也不是只是单纯的吐槽。 真的建议不要乱用语言特性。
F281M6Dh8DXpD1g2
28
F281M6Dh8DXpD1g2 2024 年 10 月 10 日
你都用 python 了还纠结这些
genesislive
29
genesislive 2024 年 10 月 10 日
matplotlib 里面应该有不少
mywaiting
30
mywaiting 2024 年 10 月 10 日
别人写的 *args **kwargs 什么垃圾,类型标识都没有,简直屎山! python 垃圾语言!
自己一把梭 *args **kwargs 内部各种对 kwargs 一会 pop 一会 setdefault 真香!干净简洁优雅! python 牛逼!
adoal
31
adoal 2024 年 10 月 10 日 ❤️ 1
用来做透传很方便
Vonrix
32
Vonrix 2024 年 10 月 11 日
每次用完就忘
G64q9J89mN5KSgmE
33
G64q9J89mN5KSgmE 2024 年 10 月 11 日
许多第三方包特别喜欢用这两玩意
调用还得看一大堆文档,操
ytmsdy
34
ytmsdy 2024 年 10 月 11 日
@Jinnrry 哈哈哈哈,确实,Python 里面的花式语法确实是最多的!就算 Python 的老司机,看到有些花式语法也要愣一下。
CodeCodeStudy
35
CodeCodeStudy 2024 年 10 月 11 日
@Jinnrry #13 golang 没有 any ,那是 typescript ,golang 的是 interface{}
InkStone
36
InkStone 2024 年 10 月 11 日
也没啥好吐槽的,所有现存的静态类型语言都有相同的机制,更不要说动态类型的了。

C 里有 void*满天飞的代码,Java 也有很多人喜欢传 Map ,Golang interface{} 一把梭,Typescript 可以用 any 退化成多写几个字母的 javascript......
qq135449773
37
qq135449773 2024 年 10 月 11 日
这东西只能说仁者见仁智者见智了,IDE 静态分析足够强的话感觉问题还不算大
qW7bo2FbzbC0
38
qW7bo2FbzbC0 2024 年 10 月 11 日
@CodeCodeStudy 新版本里面针对泛型类型指定,的确是 any 更符合语义,interface{}是 1.8 之前的用法了
lolizeppelin
39
lolizeppelin 2024 年 10 月 11 日
不能喷公司垃圾代码 转头喷 python 提供的功能 2333
lolizeppelin
40
lolizeppelin 2024 年 10 月 11 日
@ipwx
兄弟你论坛强度有点高啊..........感觉哪都能看到你 2333333333
真羡慕你啊...有那么多时间刷论坛 2333
vialon17
41
vialon17 2024 年 10 月 11 日
滥用想想都脑壳大,没有类型注释不麻烦吗?
uni
42
uni 2024 年 10 月 11 日
直接在 linter 里面禁用这些东西
每次跟别人合作 py 代码我都会要求他们把 vscode 的 py 类型检查(默认是关闭的)打开,他们可以不改但是编辑器报满屏都是红色的他们要能看到
chashao
43
chashao 2024 年 10 月 11 日
这个真他妈恶心,重构火葬场
ipwx
44
ipwx 2024 年 10 月 11 日
@lolizeppelin 啊哈哈哈,大概是因为我喜欢在没人回复的帖子下面先回复,如果有很多回复的帖子我反而不会回复也不会看回复吧。所以你经常在前几楼看见我,其实我水的不多。
lyxxxh2
45
lyxxxh2 2024 年 10 月 11 日
```
def init_tracker(self, *args):
self.tracker = CashTracker(*args)
return self
```
参数多了,挺方便啊。
Rehtt
46
Rehtt 2024 年 10 月 12 日 via Android
@CodeCodeStudy 1.18 以后就有了
// any is an alias for interface{} and is equivalent to interface{} in all ways.
type any = interface{}
CodeCodeStudy
47
CodeCodeStudy 2024 年 10 月 12 日
@qW7bo2FbzbC0 38
@Rehtt #46
感谢指出,有一段时间没看 golang 了
xiebow
48
xiebow 2024 年 10 月 13 日
@mywaiting 确实
qq78660651
49
qq78660651 2024 年 10 月 17 日
写 python 就算是自己维护,不写注释,2 周后我都不知道里面我写的啥。
关于 · 帮助文档 · 自助推广系统 · 博客 · API · FAQ · Solana · 1261 人在线 最高记录 6679 · Select Language 创意工作者们的社区 World is powered by solitude VERSION: 3.9.8.5 · 26ms · UTC 17:22 · PVG 01:22 · LAX 09:22 · JFK 12:22
♥ Do have faith in what you're doing.

AltStyle によって変換されたページ (->オリジナル) /