歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Python函數參數類型小結

Python函數參數類型小結

日期:2017/3/1 9:30:18   编辑:Linux編程

剛開始學習Python,Python相對於java確實要簡潔易用得多。內存回收類似hotspot的可達性分析, 不可變對象也如同java得Integer類型,with函數類似新版本C++的特性,總體來說理解起來比較輕松。只是函數部分參數的"*"與"**"等問題。著實令人迷糊了一把,弄清概念後寫下此文記錄下來,也希望本文能夠幫助其他初學者。

不帶“*”,"*" 與 "**"的區別

理解這個問題得關鍵在於要分開理解調用和聲明語法中3者得區別.

函數調用區別

不同類型的參數

#這裡先說明python函數調用得語法為:
func(positional_args, keyword_args,
 *tuple_grp_nonkw_args, **dict_grp_kw_args)
 
 #為了方便說明,之後用以下函數進行舉例
 def test(a,b,c,d,e):
	 print a,b,c,d,e

舉個例子來說明這4種調用方式得區別:

#-------------------------------
#positional_args方式
>>> test(1,2,3,4,5)
1 2 3 4 5

#這種調用方式的函數處理等價於
a,b,c,d,e = 1,2,3,4,5
print a,b,c,d,e

#-------------------------------
#keyword_args方式
>>> test(a=1,b=3,c=4,d=2,e=1)
1 3 4 2 1

#這種處理方式得函數處理等價於
a=1
b=3
c=4
d=2
e=1
print a,b,c,d,e

#-------------------------------
#*tuple_grp_nonkw_args方式
>>> x = 1,2,3,4,5
>>> test(*x)
1 2 3 4 5

#這種方式函數處理等價於
a,b,c,d,e = x
print a,b,c,d,e
#特別說明:x也可以為dict類型,x為dick類型時將鍵傳遞給函數
>>> y
{'a': 1, 'c': 6, 'b': 2, 'e': 1, 'd': 1}
>>> test(*y)
a c b e d

#---------------------------------
#**dict_grp_kw_args方式
>>> y
{'a': 1, 'c': 6, 'b': 2, 'e': 1, 'd': 1}
>>> test(**y)
1 2 6 1 1

#這種函數處理方式等價於
a = y['a']
b = y['b']
... #c,d,e不再贅述
print a,b,c,d,e

不同類型參數混用

接下來說明不同參數類型混用的情況,要理解不同參數混用得語法需要理解以下幾方面內容.
首先要明白,函數調用使用參數類型必須嚴格按照順序,不能隨意調換順序,否則會報錯. 如 (a=1,2,3,4,5)會引發錯誤,; (*x,2,3)也會被當成非法.
其次,函數對不同方式處理的順序也是按照上述的類型順序.因為#keyword_args方式和**dict_grp_kw_args方式對參數一一指定,所以無所謂順序.所以只需要考慮順序賦值(positional_args)和列表賦值(*tuple_grp_nonkw_args)的順序.因此,可以簡單理解為**只有**#positional_args方式,#*tuple_grp_nonkw_args方式有羅輯先後順序的.
最後,參數是不允許多次賦值的.

舉個例子說明,順序賦值(positional_args)和列表賦值(*tuple_grp_nonkw_args)的羅輯先後關系:

#只有在順序賦值,列表賦值在結果上存在羅輯先後關系
#正確的例子1
>>> x = {3,4,5}
>>> test(1,2,*x)
1 2 3 4 5
#正確的例子2
>>> test(1,e=2,*x)
1 3 4 5 2

#錯誤的例子
>>> test(1,b=2,*x)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: test() got multiple values for keyword argument 'b'

#正確的例子1,處理等價於
a,b = 1,2 #順序參數
c,d,e = x #列表參數
print a,b,c,d,e

#正確的例子2,處理等價於
a = 1 #順序參數
e = 2 #關鍵字參數
b,c,d = x #列表參數

#錯誤的例子,處理等價於
a = 1 #順序參數
b = 2 #關鍵字參數
b,c,d = x #列表參數
#這裡由於b多次賦值導致異常,可見只有順序參數和列表參數存在羅輯先後關系

函數聲明區別

理解了函數調用中不同類型參數得區別之後,再來理解函數聲明中不同參數得區別就簡單很多了.

函數聲明中的參數類型說明

函數聲明只有3種類型, arg, *arg, **arg 他們得作用和函數調用剛好相反. 調用時*tuple_grp_nonkw_args將列表轉換為順序參數,而聲明中的*arg的作用是將順序賦值(positional_args)轉換為列表. 調用時**dict_grp_kw_args將字典轉換為關鍵字參數,而聲明中得**arg則反過來將關鍵字參數(keyword_args)轉換為字典.
 *arg 和 **arg可以為空值.
 

以下舉例說明上述規則:

#arg, *arg和**arg作用舉例
def test2(a,*b,**c):
	print a,b,c
#---------------------------
#*arg 和 **arg可以不傳遞參數
>>> test2(1)
1 () {}
#arg必須傳遞參數
>>> test2()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: test2() takes at least 1 argument (0 given)

#----------------------------
#*arg將順positional_args轉換為列表
>>> test2(1,2,[1,2],{'a':1,'b':2})
1 (2, [1, 2], {'a': 1, 'b': 2}) {}
#該處理等價於
a = 1 #arg參數處理
b = 2,[1,2],{'a':1,'b':2} #*arg參數處理
c = dict() #**arg參數處理
print a,b,c

#-----------------------------
#**arg將keyword_args轉換為字典
>>> test2(1,2,3,d={1:2,3:4}, c=12, b=1)
1 (2, 3) {'c': 12, 'b': 1, 'd': {1: 2, 3: 4}}
#該處理等價於
a = 1 #arg參數處理
b= 2,3 #*arg參數處理
#**arg參數處理
c = dict()
c['d'] = {1:2, 3:4}
c['c'] = 12
c['b'] = 1
print a,b,c

處理順序問題


函數總是先處理arg類型參數,再處理*arg和**arg類型的參數. 因為*arg和**arg針對的調用參數類型不同,所以不需要考慮他們得順序.

def test2(a,*b,**c):
	print a,b,c
>>> test2(1, b=[1,2,3], c={1:2, 3:4},a=1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: test2() got multiple values for keyword argument 'a'
#這裡會報錯得原因是,總是先處理arg類型得參數
#該函數調用等價於
#處理arg類型參數:
a = 1
a = 1  #多次賦值,導致異常
#處理其他類型參數
...
print a,b,c

--------------------------------------分割線 --------------------------------------

CentOS上源碼安裝Python3.4 http://www.linuxidc.com/Linux/2015-01/111870.htm

《Python核心編程 第二版》.(Wesley J. Chun ).[高清PDF中文版] http://www.linuxidc.com/Linux/2013-06/85425.htm

《Python開發技術詳解》.( 周偉,宗傑).[高清PDF掃描版+隨書視頻+代碼] http://www.linuxidc.com/Linux/2013-11/92693.htm

Python腳本獲取Linux系統信息 http://www.linuxidc.com/Linux/2013-08/88531.htm

在Ubuntu下用Python搭建桌面算法交易研究環境 http://www.linuxidc.com/Linux/2013-11/92534.htm

Python 語言的發展簡史 http://www.linuxidc.com/Linux/2014-09/107206.htm

Python 的詳細介紹:請點這裡
Python 的下載地址:請點這裡

Copyright © Linux教程網 All Rights Reserved