Python函數中*和**的內涵究竟是什麼呢?
自己隨意寫了幾行,運行了一下發現有些神奇:
&>&>&> def Aniki(a,*b,**c):
z=[a,b,c]
return z
&>&>&> a={"a":"Ass","b":"We","c":"Can"}
&>&>&> Aniki(a)
[{"a": "Ass", "b": "We", "c": "Can"}, (), {}]
&>&>&> Aniki(*a)
["a", ("b", "c"), {}]
&>&>&> Aniki(**a)
["Ass", (), {"b": "We", "c": "Can"}]
第二種情況Aniki(*a)只取了字典的key,而最後一個Aniki(**a)為何沒有把字典中"b":2賦值給b呢?
而當我再打一段,
&>&>&> Aniki(**a,b=(1,2))
Traceback (most recent call last):
File "&
", line 1, in &
Aniki(**a,b=(1,2))
TypeError: Aniki() got multiple values for keyword argument "b"
發現其實Aniki(**a)時已經給b賦了()值,無法再賦值。
想知道*和**究竟是怎麼一回事,其原理是什麼,哪裡有相對權威一點的解釋呢?
Python的參數解析比較複雜,除了源碼並沒有很好的文檔來介紹每個細節,不過我覺得language doc里已經能解決題中的疑問了,也能滿足題主權威的要求。
6. Expressions - Python 3.6.4 documentationdocs.python.org不過我覺得鏈接中的部分沒有講清楚的就是*args和**kwargs(函數定義時的名字)是不參與運行時函數參數的名字解析的(但這並不意味著可以與位置參數和關鍵字參數重名),也是為什麼題中第一個問題b並沒有被賦值的原因。
&>&>&> def func1(a):
... pass
...
&>&>&> def func2(*a):
... pass
...
&>&>&> func1(a=1)
&>&>&> func2(a=1)
Traceback (most recent call last):
File "&
TypeError: func2() got an unexpected keyword argument "a"
這個問題基本弄清楚了,星號(asterisk)主要在函數定義和函數調用的時候使用。
- 函數定義時
- 使用單個
*
會將所有的參數,放入一個元組(tuple)供函數使用。 - 使用兩個
**
會將所有的關鍵字參數,放入一個字典(dict)供函數使用。 - 函數調用時
- 在list,tuple,set前加一個星號會把容器中的所有元素解包(unpack)變成位置參數。
- 在dict前加一個星號會把字典的鍵變成位置參數。
- 在dict前加兩個星號會把字典的鍵值對變成關鍵字參數。a={"a":"Ass","b":"We","c":"Can"}
具體到描述中的函數:
Aniki(*a)
等同於Aniki("a", "b", "c")
Aniki(**a)
等同於 Aniki(a="Ass", b="We", c="Can")
Aniki(**a,b=(1,2))
等同於 Aniki(a="Ass", b="We", c="Can",b=(1,2))
希望說清楚了。
Stack Overflow上這個問題的回答更全面,提到了星號的其他作用,推薦看一看What does ** (double star/asterisk) and * (star/asterisk) do for parameters?
Python3中新增的兩種用法:
- Keyword-Only Arguments 僅關鍵字參數
- Extended Iterable Unpacking 擴展迭代解包
僅關鍵字參數
在*args
後加入關鍵字參數,就可以要求這個參數必須以關鍵字的方式賦值。
def keyword_only(a, *args, b):
print[a, args, b]
在調用的時候,必須用關鍵字的方式賦值。單個星號*
也有相同作用,只不過不能接收無限位置參數了。
def keyword_only(a, *, b):
print[a, args, b]
擴展迭代解包
許多演算法要求以第一個元素
和 剩下的全部
這種方式分割一個序列。即
first, rest = seq[0], seq[1:]
現在可以這樣:
first, *rest = seq
或者這樣:
a, *b, c = seq
a
取得第一個元素,c
取得最後一個元素,b
取得剩下的全部。
PEP文檔:
- PEP 3102 -- Keyword-Only Arguments
- PEP 3132 -- Extended Iterable Unpacking
可以用這個在線的Python3解釋器試一試,Online Python3 Compiler - Online Python3 Editor - Online Python3 IDE - Python3 Coding Online - Practice Python3 Online - Execute Python3 Online - Compile Python3 Online - Run Python3 Online
給參數去括弧
推薦閱讀:
※對於初學者應該選擇python什麼版本呢?
※雲伺服器上如何運行python程序?
※為什麼Python第三方庫的document看起來很統一?
※Python現在用3.X的好不好?2.X我在win10打開不了IDLE又是什麼問題?