當前位置:成語大全網 - 新華字典 - python 函數參數的類型

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

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

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

print

a,b,c

2. 處理順序問題

函數總是先處理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

>>> def foo(x,y):

... def bar():

... print

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

0

>>> b()

[1, 2] 0

#可變對象仍然能被修改

>>> a.append(3)

>>>

b.func_closure[0].cell_contents

[1, 2, 3]

>>> b()

[1, 2, 3] 0