社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

Python中的星号:用途及使用方法

Python程序员 • 5 年前 • 483 次点击  

原作者:Trey Hunner

Python中 ***很常见。无论是对于编程萌新还是许多从其他编程语言(可能无与之完全等效的运算符)迁移过来的的人,这两个运算符有时可能有点儿神秘。在此,我想详述这些运算符的用途及其多种使用方式。

这些年来,***运算符的本领越来越大,我将讨论当前这些运算符的所有使用方式,并标注哪些用途仅适用于Python的现代版本。所以,如果您在Python 2时代就学会了***,我还是建议您至少浏览一下这篇文章,因为Python 3为这些运算符添加了很多新用途。

如果您初学Python,还不熟悉关键字参数(又名命名参数),那么我建议先阅读我的关于Python关键字参数的文章。

 

不在本文详述范围内的内容:

本文所述的***,指的是***前缀运算符,而不是中缀运算符。

所以指的不是乘法和乘幂:


本文所述之内容:
我们讲的是*和**前缀运算符,即在变量前面使用的*和**运算符。例如:

这包括:

  • 使用***将参数传递给函数

  • 使用***捕捉传递到函数中的参数

  • 使用*接受强制关键字参数

  • 使用*在元组拆包封期间时捕获各项

  • 使用*将迭代器解解包到列表/元组中

  • **把词典解包到其他词典

即便您认为您熟悉所有这些***的使用方法,我仍建议您查看下面的每个代码块,以确保它们都是您熟悉的。在过去的几年中,Python核心开发人员一直在为这些运算符添加新功能,***的一些新用途很容易被忽略。


星号在函数调用中解包参数

调用函数时,使用*运算符可将迭代对象解包到不同参数中:

print(*fruits)fruits列表中的所有项作为单独的参数传递到print函数调用中,我们甚至不需要知道列表包含多少个参数。

*运算符不仅仅是语法糖。如果没有*,除非列表是固定长度的,否则无法做到将特定迭代对象中的所有项作为单独的参数提交。

下面是另一个例子:

在这里,我们接受以列表为元素的列表,并返回 “转置”后的列表:

**运算符执行类似的操作,但是使用关键字参数。**操作符允许我们取一个键值对字典,并将其在函数调用中解包成关键字参数:

根据我的经验,**用于将关键字参数解包到函数调用中并不常见。我看到的最常见的地方是执行继承:调用super()通常会用到***

截至Python3.5,函数调用中***均可被多次使用。

使用*多次有时也挺方便的:

使用**多次与之类似:

但是,当使用**多次时,需要小心。Python中的函数不能多次指定相同的关键字参数,因为每个字典中与**一起使用的键必须是不同的,否则将抛出异常。

星号用于打包函数中的参数

*运算符在定义函数时,用于收集所有的位置参数到一个新的元组:

Pythonprintzip函数接受任意数量的位置参数。这个运用*的参数打包方法允许我们构造同printzip相类似的接受任意数量参数的函数。

**运算符还有另一面:在定义函数时,可以使用** 将赋予该函数的任何关键字参数捕捉到字典中:

**将捕捉我们赋予这个函数的任何关键字参数,并将其放入一个字典中,该字典将引用attributes参数。


同时使用位置参数与强制关键字参数时

Python 3始,我们现有一个特殊的语法来接受强制关键字参数。强制关键字参数是只能使用关键字语法指定的函数参数,这意味着它们不能依据相对位置指定。

若要接受强制关键字参数,可在定义函数时于*后放置命名参数:

 上面的函数可以这样使用:

参数dictionarydefault*keys之后出现,这意味着它们只能被指定为关键字参数。如果我们试图依据位置指定它们,我们将收到报错:

Python中的此种情况将在 PEP 3102详述


无位置参数只有强制关键字参数时

强制关键字参数特性很酷,但若想在不捕获过多的无限位置参数的情况下获取强制关键字参数,该如何操作?

Python语法里允许用一个略怪异的 实现它:

这个函数接受iterable参数,该参数可以按相对位置被指定(作为第一个参数),或者依据名称指定,而fillvalue参数是强制关键字参数。这意味着我们可以这样调用with_previous

但不是这样:

此函数接受两个参数,其一fillvalue必须被指定为关键字参数。

我在捕捉任意数量的位置参数时通常使用强制关键字参数,但有时还是会使用*来强制参数仅通过位置指定。

Python内置的sorted函数实际上使用了这种方法。如果查看sorted的帮助信息,您将看到以下内容:

此例有一个单独的*,在sorted 的文档化的参数中。


星号用于元组解包

Python 3还新增了一种使用*运算符的方法,它只与前文所述的函数定义与函数调用时*表现出的特性有关。

如今 * 运算符也可以用于元组解包:

如果您想知道“自己的代码中可以在哪里使用它”,请看一下我所著关于Python中的元组解包的文章中的示例。在这篇文章中,我展示了使用*运算符替代完成序列切片的一些场景。

通常,当我讲授 * 时,总强调只能在一个简单的多重赋值调用中使用一种 *表达。这在技术上是不正确的,因为在嵌套形式的解包中可以使用两种(我在元组解包文章中会谈到嵌套形式的解包):

不过我还没找到这个的好例子,即使你找到了,我也不建议使用它,因为它看起来有点晦涩。

Python 3PEPPEP 3132 加入了这个,并不长。

未完,下篇请看今日推送的第二篇文字


英文原文:http://treyhunner.com/2018/10/asterisks-in-python-what-they-are-and-how-to-use-them/
译者:盈韬



今天看啥 - 高品质阅读平台
本文地址:http://www.jintiankansha.me/t/aUkGum5VoQ
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/25121
 
483 次点击