问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

Python小技巧:?args 和 kwargs 的乐趣

发布网友 发布时间:2024-10-02 22:34

我来回答

1个回答

热心网友 时间:2024-11-01 14:56

我曾经和一个聪明的 Pythonista 结对编程,每次他输入带有可选或关键字参数的函数定义时,他都会惊呼“argh!”和“kwargh!”。 要不然我们相处的很好,我猜想这就是学术界编程最终对人所带来的影响吧。 现在args和 kwargs参数仍然是 Python 中非常有用的特性,而且理解它们的威力将使您成为更有效的开发人员。 那么“args”和“kwargs”参数用来做什么呢?

它们允许一个函数接受可选参数,因此你能够在你的模块和类里创建弹性APIs。 示例代码如下:

In [2]: def foo(required, *args, **kwargs): ...: print(required) ...: if args: ...: print(args) ...: if kwargs: ...: print(kwargs)

上面的函数需要至少一个叫做“必须的”参数,但是它也能接受额外的位置参数和关键字参数。

如果我们调用带有附加参数的函数,参数将会收集额外的位置参数作为一个元组,因为这个参数的名字有一个*(单星号)前缀。

同样地,kwargs将收集额外的关键字参数作为一个字典,因为这个参数名字有**(双星号)前缀。

如果没有附加参数被传递给函数。args 和 kwargs 可以为空。

当我们调用带有参数的不同组合的函数时,你会看到在args和kwargs内部参数。 Python如何收集它们,根据它们是否为位置参数或者关键字参数。代码如下:

In [3]: foo()---------------------------------------------------------------------------TypeError Traceback (most recent call last)<ipython-input-3-c19b6d9633cf> in <mole>----> 1 foo()TypeError: foo() missing 1 required positional argument: 'required'In [4]: foo('hello')helloIn [5]: foo('hello', 1, 2, 3)hello(1, 2, 3)In [6]: foo('hello', 1, 2, 3, key1='value', key2=999)hello(1, 2, 3){'key1': 'value', 'key2': 999}

我要明确一下,调用args和kwargs参数是简单的命名惯例。 像之前的例子里,如果称他们

parms和argv也可以。实际上语法分别是单星号(

)或者双星号()。 然而,我还是推荐你还是坚持可接受的命名惯例以避免混淆。(而且每隔一段时间还有机会喊“argh!”和“kwargh!”)。

## 转发可选或者关键字参数

有可能从一个函数到另一个函数传递可选或者关键字参数。 当你调用要转发参数的函数时,你可以通过使用解包参数操作符

*。在你传递之前这也给你一个机会修改参数。

示例如下:

In [8]: def foo(x, *args, **kwargs): ...: kwarg['name'] = 'Alice' ...: new_args = args + ('extra', ) ...: bar(x, *new_args, **kwargs)

这种技术对于子类化和编写包装函数很有用。 例如,您可以使用它来扩展父类的行为,而不必在子类中复制其构造函数的完整签名。

如果您使用的 API 可能会在您的控制之外发生变化,这会非常方便,示例代码如下:

In [9]: class Car: ...: def __init__(self, color, mileage): ...: self.color = color ...: self.mileage = mileage ...: In [10]: class AlwaysBlueCar(Car):...: def __init__(self, *args, **kwargs):...: super().__init__(*args, **kwargs)...: self.color = 'blue'In [12]: AlwaysBlueCar('green', 48392).colorOut[12]: 'blue'

AlwaysBlueCar 构造函数只是将所有参数传递给它的父类,然后覆盖一个内部属性。 这意味着如果父类构造函数发生更改,AlwaysBlueCar 很有可能仍会按预期运行。 这里的缺点是 AlwaysBlueCar 构造函数现在有一个相当无用的签名——如果不查找父类,我们不知道它需要什么参数。 通常,您不会将这种技术用于您自己的类层次结构。更有可能的情况是您想要修改或覆盖某些您无法控制的外部类中的行为。 但这总是危险的领域,所以最好小心(否则你可能很快就会有另一个理由尖叫“argh!”)。

这种技术可能有用的另一种情况是编写包装函数,例如装饰器。在那里,您通常还希望接受要传递给包装函数的任意参数。

而且,如果我们可以在不必复制和粘贴原始函数签名的情况下做到这一点,那可能更易于维护:

import functoolsdef trace(f):...: @functools.wraps(f)...: def decorated_function(*args, **kwargs):...: print(f, args, kwargs)...: result = f(*args, **kwargs)...: print(result)...: return decorated_functionIn [11]: @trace...: def greet(greeting, name):...: return '{}, {}!'.format(greeting, name)In [14]: greet('Hello', 'Bob')<function greet at 0x7fefa69db700> ('Hello', 'Bob') {}Hello, Bob!

使用像这样的技术,有时很难在使代码足够明确的想法和遵守不要重复自己(DRY)原则的想法之间取得平衡。 这可能永远是一个艰难的选择。如果你能从同事那里得到第二个意见,我鼓励你尝试一下。

以上就是本次分享的所有内容,想要了解更多欢迎前往公众号:Python 编程学习圈,每日干货分享

原文:https://juejin.cn/post/7101134603032723470
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
鱼竿18调28调什么意思 世界杯的比赛规则是什么?跪谢! 世界杯的规则?简洁一点。 中考数学题型是不是和二模的题型一样 二模数学陆拾多分中考能冲上玖拾分吗? 大家都会选什么价位的电动车来代步呢?欧拉iQ值得买吗? 欧拉iQ成都车展上市了,价格有人说不贵,但独特的造型年轻人会接受吗? 金店金价根据什么来的 1a的插头可以用16a的插座吗 动物森友会隐藏成就攻略 7个隐藏成就介绍 手机WLAN连的起并且是满格信号电脑上网也能上但为什么手机连起WLAN... 长虹智能电视质量如何 为什么玩DNF会飘? 联通无线网卡信号满格玩dnf卡吗 腾达ac10路由器评测 腾达路由器ac8和ac10哪个好 㐫这是什么剧?电影? 연애의맛. 是什么电影的名字? 政审科普系列文章——征信报告 为什么台式电脑插了网线还没有联网? 醪糟是热性还是凉性(醪糟有祛湿作用吗方法) 乘坐动车可以带1.7米左右的竿桶吗(就是放鱼竿的桶,直径在15厘米... 晚上老是失眠 多梦 上课没精神老打瞌睡 求解决方法 老是瞌睡没精神什么原因 F:\360Downloads\AutoCAD2007\AutoCAD2007简体中文版\Bin\acadFeui\Pro... 草坪一般种什么草 庭院草籽什么品种好? 新乡东站要求24小时核酸吗 11月7号去新乡东站高速口让下吗? 采集信息可以进新乡东站吗 Python进行跨域HTTP请求的解决方案 笔记本用无线网络玩DNF无法进入游戏。 DNFPK准备界面显示连接不卡 一开打就变红 dnf为什么我的狂战比别的狂战面板速度快 同一种连发 可是我打起来没他... tcl长虹哪个品牌好 "Windows 98 原版光盘 景象ISO 已集成多功能光盘"哪里有的下?谢谢 ...情人,但多半是男人约女人,原配只想告小三可以吗? 摩托车下乡资金来源 摩托车下乡考试和不下乡有什么区别? 关于摩托车下乡补贴的问题 摩托车下乡补贴问题 我想请问,有什么办法可以使125摩托车增大功率 摩托车发动机功率小,换缸套活塞可以吗 为什么京东提前还款减额度 如何改变摩托车扭矩.以及加大功率还有改变变速比 谢谢指教 支付宝借呗借了18000期限是一年,用了4个月提前还款了会降额吗?_百度知... ‘希腊怪兽’字母哥4代签名鞋实战测评 青春易逝,惟有珍惜(青春的十首古诗词) 我在携程上订的火车票,怎么会消失了? 幼儿园都教些什么内容呢?