函數(shù)的參數(shù)
1、默認值參數(shù)
有時候,我們自定義的函數(shù)中,如果調(diào)用的時候沒有設(shè)置參數(shù),需要給個默認值,這時候就需要用到默認值參數(shù)了。
# -*- coding: UTF-8 -*- def print_user_info( name , age , sex = '男' ): # 打印用戶信息 print('昵稱:{}'.format(name) , end = ' ') print('年齡:{}'.format(age) , end = ' ') print('性別:{}'.format(sex)) return; # 調(diào)用 print_user_info 函數(shù) print_user_info( '兩點水' , 18 , '女') print_user_info( '三點水' , 25 )
輸出結(jié)果:
昵稱:兩點水 年齡:18 性別:女 昵稱:三點水 年齡:25 性別:男
可以看到,當(dāng)你設(shè)置了默認參數(shù)的時候,在調(diào)用函數(shù)的時候,不傳該參數(shù),就會使用默認值。但是這里需要注意的一點是:只有在形參表末尾的那些參數(shù)可以有默認參數(shù)值,也就是說你不能在聲明函數(shù)形參的時候,先聲明有默認值的形參而后聲明沒有默認值的形參。這是因為賦給形參的值是根據(jù)位置而賦值的。例如,def func(a, b=1) 是有效的,但是 def func(a=1, b) 是 無效 的。
默認值參數(shù)就這樣結(jié)束了嗎?還沒有的,細想一下,如果參數(shù)中是一個可修改的容器比如一個 lsit (列表)或者 dict (字典),那么我們使用什么來作為默認值呢?我們可以使用 None 作為默認值。就像下面這個例子一樣:
# 如果 b 是一個 list ,可以使用 None 作為默認值 def print_info( a , b = None ): if b is None : b=[] return;
認真看下例子,會不會有這樣的疑問呢?在參數(shù)中我們直接 b=[] 不就行了嗎?也就是寫成下面這個樣子:
def print_info( a , b = [] ): return;
對不對呢?運行一下也沒發(fā)現(xiàn)錯誤啊,可以這樣寫嗎?這里需要特別注意的一點:默認參數(shù)的值是不可變的對象,比如None、True、False、數(shù)字或字符串,如果你像上面的那樣操作,當(dāng)默認值在其他地方被修改后你將會遇到各種麻煩。這些修改會影響到下次調(diào)用這個函數(shù)時的默認值。
示例如下:
# -*- coding: UTF-8 -*- def print_info( a , b = [] ): print(b) return b ; result = print_info(1) result.append('error') print_info(2)
輸出的結(jié)果:
[] ['error']
認真觀察,你會發(fā)現(xiàn)第二次輸出的值根本不是你想要的,因此切忌不能這樣操作。
還有一點,有時候我就是不想要默認值啊,只是想單單判斷默認參數(shù)有沒有值傳遞進來,那該怎么辦?我們可以這樣做:
_no_value =object() def print_info( a , b = _no_value ): if b is _no_value : print('b 沒有賦值') return;
這里的 object 是python中所有類的基類。 你可以創(chuàng)建 object 類的實例,但是這些實例沒什么實際用處,因為它并沒有任何有用的方法, 也沒有任何實例數(shù)據(jù)(因為它沒有任何的實例字典,你甚至都不能設(shè)置任何屬性值)。 你唯一能做的就是測試同一性。也正好利用這個特性,來判斷是否有值輸入。
2、關(guān)鍵字參數(shù)
在 Python 中,可以通過參數(shù)名來給函數(shù)傳遞參數(shù),而不用關(guān)心參數(shù)列表定義時的順序,這被稱之為關(guān)鍵字參數(shù)。使用關(guān)鍵參數(shù)有兩個優(yōu)勢 :
一、由于我們不必擔(dān)心參數(shù)的順序,使用函數(shù)變得更加簡單了。
二、假設(shè)其他參數(shù)都有默認值,我們可以只給我們想要的那些參數(shù)賦值
# -*- coding: UTF-8 -*- def print_user_info( name , age , sex = '男' ): # 打印用戶信息 print('昵稱:{}'.format(name) , end = ' ') print('年齡:{}'.format(age) , end = ' ') print('性別:{}'.format(sex)) return; # 調(diào)用 print_user_info 函數(shù) print_user_info( name = '兩點水' ,age = 18 , sex = '女') print_user_info( name = '兩點水' ,sex = '女', age = 18 )
輸出的值:
昵稱:兩點水 年齡:18 性別:女 昵稱:兩點水 年齡:18 性別:女
3、不定長參數(shù)
有時我們在設(shè)計函數(shù)接口的時候,可會需要可變長的參數(shù)。也就是說,我們事先無法確定傳入的參數(shù)個數(shù)。Python 提供了一種元組的方式來接受沒有直接定義的參數(shù)。這種方式在參數(shù)前邊加星號 * 。如果在函數(shù)調(diào)用時沒有指定參數(shù),它就是一個空元組。我們也可以不向函數(shù)傳遞未命名的變量。
例如:
# -*- coding: UTF-8 -*- def print_user_info( name , age , sex = '男' , * hobby): # 打印用戶信息 print('昵稱:{}'.format(name) , end = ' ') print('年齡:{}'.format(age) , end = ' ') print('性別:{}'.format(sex) ,end = ' ' ) print('愛好:{}'.format(hobby)) return; # 調(diào)用 print_user_info 函數(shù) print_user_info( '兩點水' ,18 , '女', '打籃球','打羽毛球','跑步')
輸出的結(jié)果:
昵稱:兩點水 年齡:18 性別:女 愛好:('打籃球', '打羽毛球', '跑步')
通過輸出的結(jié)果可以知道,*hobby是可變參數(shù),且 hobby其實就是一個 tuple (元祖)
可變長參數(shù)也支持關(guān)鍵參數(shù),沒有被定義的關(guān)鍵參數(shù)會被放到一個字典里。這種方式即是在參數(shù)前邊加 **,更改上面的示例如下:
# -*- coding: UTF-8 -*- def print_user_info( name , age , sex = '男' , ** hobby ): # 打印用戶信息 print('昵稱:{}'.format(name) , end = ' ') print('年齡:{}'.format(age) , end = ' ') print('性別:{}'.format(sex) ,end = ' ' ) print('愛好:{}'.format(hobby)) return; # 調(diào)用 print_user_info 函數(shù) print_user_info( name = '兩點水' , age = 18 , sex = '女', hobby = ('打籃球','打羽毛球','跑步'))
輸出的結(jié)果:
昵稱:兩點水 年齡:18 性別:女 愛好:{'hobby': ('打籃球', '打羽毛球', '跑步')}
通過對比上面的例子和這個例子,可以知道,*hobby是可變參數(shù),且 hobby其實就是一個 tuple (元祖),**hobby是關(guān)鍵字參數(shù),且 hobby 就是一個 dict (字典)
4、只接受關(guān)鍵字參數(shù)
關(guān)鍵字參數(shù)使用起來簡單,不容易參數(shù)出錯,那么有些時候,我們定義的函數(shù)希望某些參數(shù)強制使用關(guān)鍵字參數(shù)傳遞,這時候該怎么辦呢?
將強制關(guān)鍵字參數(shù)放到某個*參數(shù)或者單個*后面就能達到這種效果,比如:
# -*- coding: UTF-8 -*- def print_user_info( name , *, age , sex = '男' ): # 打印用戶信息 print('昵稱:{}'.format(name) , end = ' ') print('年齡:{}'.format(age) , end = ' ') print('性別:{}'.format(sex)) return; # 調(diào)用 print_user_info 函數(shù) print_user_info( name = '兩點水' ,age = 18 , sex = '女' ) # 這種寫法會報錯,因為 age ,sex 這兩個參數(shù)強制使用關(guān)鍵字參數(shù) #print_user_info( '兩點水' , 18 , '女' ) print_user_info('兩點水',age='22',sex='男')
通過例子可以看,如果 age , sex 不適用關(guān)鍵字參數(shù)是會報錯的。
很多情況下,使用強制關(guān)鍵字參數(shù)會比使用位置參數(shù)表意更加清晰,程序也更加具有可讀性。使用強制關(guān)鍵字參數(shù)也會比使用 **kw 參數(shù)更好且強制關(guān)鍵字參數(shù)在一些更高級場合同樣也很有用。