Redian新闻
>
Python小技巧:​args 和 kwargs 的乐趣

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

科技

这篇文章是伟兄给我的稿子,总结实用、到位。另外,欢迎访问并关注他的博客:
https://jl-zhenlaixiaowei.blog.csdn.net/
我曾经和一个聪明的 Pythonista 结对编程,每次他输入带有可选或关键字参数的函数定义时,他都会惊呼“argh!”和“kwargh!”。
要不然我们相处的很好,我猜想这就是学术界编程最终对人所带来的影响吧。
现在argskwargs参数仍然是 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 <module>
----> 1 foo()

TypeError: foo() missing 1 required positional argument: 'required'
In [4]: foo('hello')
hello
In [5]: foo('hello'123)
hello
(123)

In [6]: foo('hello'123, key1='value', key2=999)
hello
(123)
{'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).color
Out[12]: 'blue'
AlwaysBlueCar 构造函数只是将所有参数传递给它的父类,然后覆盖一个内部属性。
这意味着如果父类构造函数发生更改,AlwaysBlueCar 很有可能仍会按预期运行。
这里的缺点是 AlwaysBlueCar 构造函数现在有一个相当无用的签名——如果不查找父类,我们不知道它需要什么参数。
通常,您不会将这种技术用于您自己的类层次结构。更有可能的情况是您想要修改或覆盖某些您无法控制的外部类中的行为。
但这总是危险的领域,所以最好小心(否则你可能很快就会有另一个理由尖叫“argh!”)。
这种技术可能有用的另一种情况是编写包装函数,例如装饰器。在那里,您通常还希望接受要传递给包装函数的任意参数。
而且,如果我们可以在不必复制和粘贴原始函数签名的情况下做到这一点,那可能更易于维护:
import functools
def trace(f):
    ...:     @functools.wraps(f)
    ...:     def decorated_function(*args, **kwargs):
    ...:         print(f, args, kwargs)
    ...:         result = f(*args, **kwargs)
    ...:         print(result)
    ...:     return decorated_function
    
In [11]: @trace
    ...: def greet(greeting, name):
    ...:     return '{}, {}!'.format(greeting, name)
In [14]: greet('Hello''Bob')
<function greet at 0x7fefa69db700> ('Hello''Bob') {}
Hello, Bob!
使用像这样的技术,有时很难在使代码足够明确的想法和遵守不要重复自己(DRY)原则的想法之间取得平衡。
这可能永远是一个艰难的选择。如果你能从同事那里得到第二个意见,我鼓励你尝试一下。

微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
20 Things We Learned from China’s 7th CensusPython根据经纬度生成并调用地图在 Python 中使用机器学习来检测钓鱼链接 | Linux 中国Linux 命令行小技巧 – !叹号的用处“地球”应该写成the earth还是the Earth?Python批量将Photoshop文件保存为图片明星瘦身小技巧!多减 5 斤肥肉,消耗 21600 千卡,还能矫正体态【亿福资讯】控制贷款利率的几个小技巧Python,数据岗位的技术弄潮儿StarkWare:以太坊扩容最佳团队,80 亿美元高估了吗?利用python腾讯在线文档的修改Chase IHG Premier 福利之 $25 United Travel Bank Cash 使用小技巧《和风细雨》(91)爱的山里行【梦呓流年】第十七章:摆正体位(四)|男男恋情还属于隐晦禁忌的领域|原创长篇轻小说让女朋友听了直夸的说骚话小技巧!!!Thonny:在学校教授 Python 编程的理想 IDE | Linux 中国在小红书,每天 get 一个窜稀小技巧‘Hot, Hot, Hot’: China Hit with Blistering Heat Wave普京很像墨索里尼?2小时完成的第一个副业单子:Python修正excel表格数据[电脑] 搭积木的乐趣——JM Customized D+ v2.0一体水+风冷双方案装机彭博社开源 Memray,一个 Python 内存剖析器 | Linux 中国使用 LibreOffice 键盘快捷键的小技巧 | Linux 中国白事红办——俄粉奇异的脑回路5个公园拍照的小技巧,不花钱拍大片又一个提升颜值的小技巧!(躺着不动版)机器学习:使用 Python 进行分类 | Linux 中国终于! 多伦多动物园即日起取消疫苗证明, 正常逛园子的乐趣回来了~Marcus by Goldman Sachs Savings 银行账户【1.20% APY + 额外1.0% APY三个月】使用 Python 的 requests 和 Beautiful Soup 来分析网页 | Linux 中国硬核观察 #645 JavaScript 和 Python 继续统治编程语言,但 Rust 在崛起机器学习:使用 Python 进行预测 | Linux 中国喜大普奔!Python终行动,天下苦GIL久矣Python中常见魔法方法介绍人物头像
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。