當前位置:
首頁 > 知識 > Python中的星號:用途及使用方法

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

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

原作者:Trey Hunner

Python中 *和**很常見。無論是對於編程萌新還是許多從其他編程語言(可能無與之完全等效的運算符)遷移過來的的人,這兩個運算符有時可能有點兒神秘。在此,我想詳述這些運算符的用途及其多種使用方式。

這些年來,*和**運算符的本領越來越大,我將討論當前這些運算符的所有使用方式,並標註哪些用途僅適用於Python的現代版本。所以,如果您在Python 2時代就學會了*和**,我還是建議您至少瀏覽一下這篇文章,因為Python 3為這些運算符添加了很多新用途。

如果您初學Python,還不熟悉關鍵字參數(又名命名參數),那麼我建議先閱讀我的關於Python關鍵字參數的文章。

不在本文詳述範圍內的內容:

本文所述的*和**,指的是*和**前綴運算符,而不是中綴運算符。

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

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

本文所述之內容:

我們講的是*和**前綴運算符,即在變數前面使用的*和**運算符。例如:

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

這包括:

  • 使用*和**將參數傳遞給函數

  • 使用*和**捕捉傳遞到函數中的參數

  • 使用*接受強制關鍵字參數

  • 使用*在元組拆包封期間時捕獲各項

  • 使用*將迭代器解解包到列表/元組中

  • 用**把詞典解包到其他詞典

即便您認為您熟悉所有這些*和**的使用方法,我仍建議您查看下面的每個代碼塊,以確保它們都是您熟悉的。在過去的幾年中,Python核心開發人員一直在為這些運算符添加新功能,*和**的一些新用途很容易被忽略。

星號在函數調用中解包參數

調用函數時,使用*運算符可將迭代對象解包到不同參數中:

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

print(*fruits)將fruits列表中的所有項作為單獨的參數傳遞到print函數調用中,我們甚至不需要知道列表包含多少個參數。

*運算符不僅僅是語法糖。如果沒有*,除非列表是固定長度的,否則無法做到將特定迭代對象中的所有項作為單獨的參數提交。

下面是另一個例子:

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

在這裡,我們接受以列表為元素的列表,並返回 「轉置」後的列表:

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

**運算符執行類似的操作,但是使用關鍵字參數。**操作符允許我們取一個鍵值對字典,並將其在函數調用中解包成關鍵字參數:

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

根據我的經驗,**用於將關鍵字參數解包到函數調用中並不常見。我看到的最常見的地方是執行繼承:調用super通常會用到*和**。

截至Python3.5,函數調用中*和**均可被多次使用。

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

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

使用**多次與之類似:

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

但是,當使用**多次時,需要小心。Python中的函數不能多次指定相同的關鍵字參數,因為每個字典中與**一起使用的鍵必須是不同的,否則將拋出異常。

星號用於打包函數中的參數

*運算符在定義函數時,用於收集所有的位置參數到一個新的元組:

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

Python的print和zip函數接受任意數量的位置參數。這個運用*的參數打包方法允許我們構造同print和zip相類似的接受任意數量參數的函數。

**運算符還有另一面:在定義函數時,可以使用**將賦予該函數的任何關鍵字參數捕捉到字典中:

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

**將捕捉我們賦予這個函數的任何關鍵字參數,並將其放入一個字典中,該字典將引用attributes參數。

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

同時使用位置參數與強制關鍵字參數時

自Python 3始,我們現有一個特殊的語法來接受強制關鍵字參數。強制關鍵字參數是只能使用關鍵字語法指定的函數參數,這意味著它們不能依據相對位置指定。

若要接受強制關鍵字參數,可在定義函數時於*後放置命名參數:

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

上面的函數可以這樣使用:

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

參數dictionary和default在*keys之後出現,這意味著它們只能被指定為關鍵字參數。如果我們試圖依據位置指定它們,我們將收到報錯:

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

Python中的此種情況將在 PEP 3102詳述

無位置參數只有強制關鍵字參數時

強制關鍵字參數特性很酷,但若想在不捕獲過多的無限位置參數的情況下獲取強制關鍵字參數,該如何操作?

Python語法里允許用一個略怪異的 * 實現它:

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

這個函數接受iterable參數,該參數可以按相對位置被指定(作為第一個參數),或者依據名稱指定,而fillvalue參數是強制關鍵字參數。這意味著我們可以這樣調用with_previous:

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

但不是這樣:

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

此函數接受兩個參數,其一fillvalue必須被指定為關鍵字參數。

我在捕捉任意數量的位置參數時通常使用強制關鍵字參數,但有時還是會使用*來強制參數僅通過位置指定。

Python內置的sorted函數實際上使用了這種方法。如果查看sorted的幫助信息,您將看到以下內容:

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

此例有一個單獨的*,在sorted 的文檔化的參數中。

星號用於元組解包

Python 3還新增了一種使用*運算符的方法,它只與前文所述的函數定義與函數調用時*表現出的特性有關。

如今 * 運算符也可以用於元組解包:

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

如果您想知道「自己的代碼中可以在哪裡使用它」,請看一下我所著關於Python中的元組解包的文章中的示例。在這篇文章中,我展示了使用*運算符替代完成序列切片的一些場景。

通常,當我講授 * 時,總強調只能在一個簡單的多重賦值調用中使用一種 *表達。這在技術上是不正確的,因為在嵌套形式的解包中可以使用兩種(我在元組解包文章中會談到嵌套形式的解包):

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

不過我還沒找到這個的好例子,即使你找到了,我也不建議使用它,因為它看起來有點晦澀。

Python 3中PEP是PEP 3132 加入了這個,並不長。

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

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

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Python部落 的精彩文章:

IPython 7.0發布:Async REPL
Python 的後Guido時代

TAG:Python部落 |