本文目錄一覽:
簡述python函數中參數的幾種形態
在調用函數時,通常會傳遞參數,函數內部的代碼保持不變,針對 不同的參數處理不同的數據。
有位置傳參、關鍵字傳參、默認值參數、多值參數等。
1、參數傳遞
形參和實參:
形參:定義 函數時的 參數變量
實參:調用 函數時,使用的參數變量
參數傳遞的過程,就是 把實參的引用 傳遞給 形參 ,使用實參的值來執行函數體的過程。
在 Python 中,函數的 實參/返回值 都是是靠 引用 來傳遞來的
2、位置實參
按照參數位置,依次傳遞參數,這是最普通的方式。

python 函數參數的類型
1. 不同類型的參數簡述
#這裡先說明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
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不再贅述
a,b,c,d,e
2.
不同類型參數混用需要注意的一些細節
接下來說明不同參數類型混用的情況,要理解不同參數混用得語法需要理解以下幾方面內容.
首先要明白,函數調用使用參數類型必須嚴格按照順序,不能隨意調換順序,否則會報錯. 如 (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多次賦值導致異常,可見只有順序參數和列表參數存在羅輯先後關係
函數聲明區別
理解了函數調用中不同類型參數得區別之後,再來理解函數聲明中不同參數得區別就簡單很多了.
1. 函數聲明中的參數類型說明
函數聲明只有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
a,b,c
2. 處理順序問題
函數總是先處理arg類型參數,再處理*arg和**arg類型的參數.
因為*arg和**arg針對的調用參數類型不同,所以不需要考慮他們得順序.
複製代碼
代碼如下:
def test2(a,*b,**c):
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
def foo(x,y):
… def bar():
x,y
… return bar
…
#查看func_closure的引用信息
a =
[1,2]
b = foo(a,0)
b.func_closure[0].cell_contents
[1, 2]
b.func_closure[1].cell_contents
b()
[1, 2] 0
#可變對象仍然能被修改
a.append(3)
b.func_closure[0].cell_contents
[1, 2, 3]
b()
[1, 2, 3] 0
Python的函數和參數
parameter 是函數定義的參數形式
argument 是函數調用時傳入的參數實體。
對於函數調用的傳參模式,一般有兩種:
此外,
也是關鍵字傳參
python的函數參數定義一般來說有五種: 位置和關鍵字參數混合 , 僅位置參數 , 僅關鍵字參數 , 可變位置參數 , 可變關鍵字參數 。其中僅位置參數的方式僅僅是一個概念,python語法中暫時沒有這樣的設計。
通常我們見到的函數是位置和關鍵字混合的方式。
既可以用關鍵字又可以用位置調用
或
這種方式的定義只能使用關鍵字傳參的模式
f(*some_list) 與 f(arg1, arg2, …) (其中some_list = [arg1, arg2, …])是等價的
網絡模塊request的request方法的設計
多數的可選參數被設計成可變關鍵字參數
有多種方法能夠為函數定義輸出:
非常晦澀
如果使用可變對象作為函數的默認參數,會導致默認參數在所有的函數調用中被共享。
例子1:
addItem方法的data設計了一個默認參數,使用不當會造成默認參數被共享。
python裡面,函數的默認參數被存在__default__屬性中,這是一個元組類型
例子2:
在例子1中,默認參數是一個列表,它是mutable的數據類型,當它寫進 __defauts__屬性中時,函數addItem的操作並不會改變它的id,相當於 __defauts__只是保存了data的引用,對於它的內存數據並不關心,每次調用addItem,都可以修改 addItem.__defauts__中的數據,它是一個共享數據。
如果默認參數是一個imutable類型,情況將會不一樣,你無法改變默認參數第一次存入的值。
例子1中,連續調用addItem(‘world’) 的結果會是
而不是期望的
python中的range函數
Python2.X range()函數可創建一個整數列表,一般用在for循環中。
Python3 range()函數返回的是一個可迭代對象,類型是對象,而不是列表類型,所以打印的時候不會打印列表。
Python3 list()函數是對象迭代器,可以把range()返回的可迭代對象轉為一個列表,返回的變量類型為列表。
Python2 range()函數返回的是列表。
Python range()函數語法
range(start, stop[,step])
參數說明:
start:計數從start開始,默認是從0開始;比如:range(5)等價於range(0,5)。
stop:計數到stop結束,但不包括stop;比如:range(0,5)是[0, 1, 2, 3, 4]沒有5。
step:步長,默認為1;比如:range(0,5)等價於range(0,5,1)。
原創文章,作者:CYNR3,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/130358.html