python可變參數調用函數問題,python可變參數函數
一直使用python實現一些想法,最近在使用python的過程中出現這樣一個需求,定義了一個函數,第一個是普通參數,第二個是預設參數,後面還有可變參數,在最初學習python的時候,都知道非關鍵字可變參數和關鍵字可變參數兩種,調用的方式也非常多種多樣,這裡主要提出一個比較隱含的問題,並將各種可能出現的情況進行了探討。
函式宣告格式
python雖然不支援函數重載,但是通過對函數參數的眾多特性的支援基本彌補了。函式宣告的通式如下:
def func(argv1,argv2...[,argv_d = default1,...]\ [,*var_argv][,**var_key_argv])
這是python函式宣告的通式,首先是普通參數若干個,也可以沒有,接著是帶預設值的參數,然後是非關鍵字可變參數,最後是關鍵字可變參數。這為python提供的強大函數調用奠定了基礎。
函數調用
正是在函數調用的過程中遇到了問題。為了說明,我定義了一個如下的函數進行說明:
def f1(a,b=1,*var): print a,'\t',b,'\t',vardef f2(a,b=1,**var): print a,'\t',v,'\t',var
首先普通參數可以使用按位置的方式調用,同時可以使用按形參關鍵字調用。預設值參數也是使用位置方式匹配或者關鍵字調用。執行個體如下:
這裡沒有使用後面的可變參數,一切都沒有問題。問題是,本人遇到的一個需求是,預設參數需要就是使用預設值調用,同時還有可變參數,而且是非關鍵字參數,那麼調用時就會出現下面的情況:
可以看到,通過非關鍵字可變參數傳入參數之後,python會預設把非關鍵字可變參數的前面若干個(這裡是1個)當做預設參數,這裡是因為我沒有提供預設參數b的值,正是這個原因,在我的程式中一直沒發現。後來自習思考一下,發現Python解譯器做出這樣的決定還是有一定的道理的,因為非關鍵字可變參數是預設參數之後的若干個參數,而在調用的時候由於沒有傳入預設參數的值,Python無法判斷到底從哪裡開始是可變參數,因此在沒有傳入預設參數的值時,就依次從非關鍵字參數(調用者認為的)中按照順序抽取去當做預設參數的值,這從側面論證了非關鍵字可變參數在python內部是和普通參數預設參數一併處理的。
雖然上述調用有些極端,但是確實會出現這樣的需求,那麼可以使用關鍵字可變參數進行替換,上述問題就可以解決了,因為解譯器是可以區別關鍵字參數和預設參數的,調用如下:
在使用關鍵字可變參數時,還有一個重要問題就是,關鍵字參數的索引值不能有普通參數或者預設參數的參數名重複,這從側面論證了,python對關鍵字調用和關鍵字可變參數在內部都是經過同一個字典儲存的,因此不能有重複的鍵,調用如下:
上述遇到的問題是在實際操作過程中遇到的,一般從各種教程、書本學習python都只是說明上述的函式宣告和調用的方式,但是幾乎沒有這種實際操作中可能遇到的點點滴滴,因此學習任何東西最好的方式就動手,這個真理永遠不會變啦!