python可變引數呼叫函式問題

2021-07-03 04:05:29 字數 1819 閱讀 6118

一直使用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',var

deff2

(a,b=1,**var):

print a,'\t',v,'\t',var

首先普通引數可以使用按位置的方式呼叫,同時可以使用按形參關鍵字呼叫。預設值引數也是使用位置方式匹配或者關鍵字呼叫。例項如下:

這裡沒有使用後面的可變引數,一切都沒有問題。問題是,本人遇到的乙個需求是,預設引數需要就是使用預設值呼叫,同時還有可變引數,而且是非關鍵字引數,那麼呼叫時就會出現下面的情況:

可以看到,通過非關鍵字可變引數傳入引數之後,python會預設把非關鍵字可變引數的前面若干個(這裡是1個)當做預設引數,這裡是因為我沒有提供預設引數b的值,正是這個原因,在我的程式中一直沒發現。後來自習思考一下,發現python直譯器做出這樣的決定還是有一定的道理的,因為非關鍵字可變引數是預設引數之後的若干個引數,而在呼叫的時候由於沒有傳入預設引數的值,python無法判斷到底從**開始是可變引數,因此在沒有傳入預設引數的值時,就依次從非關鍵字引數(呼叫者認為的)中按照順序抽取去當做預設引數的值,這從側面論證了非關鍵字可變引數在python內部是和普通引數預設引數一併處理的

雖然上述呼叫有些極端,但是確實會出現這樣的需求,那麼可以使用關鍵字可變引數進行替換,上述問題就可以解決了,因為直譯器是可以區別關鍵字引數和預設引數的,呼叫如下:

在使用關鍵字可變引數時,還有乙個重要問題就是,關鍵字引數的鍵值不能有普通引數或者預設引數的引數名重複,這從側面論證了,python對關鍵字呼叫和關鍵字可變引數在內部都是經過同乙個字典儲存的,因此不能有重複的鍵,呼叫如下:

上述遇到的問題是在實際操作過程中遇到的,一般從各種教程、書本學習python都只是說明上述的函式宣告和呼叫的方式,但是幾乎沒有這種實際操作中可能遇到的點點滴滴,因此學習任何東西最好的方式就動手,這個真理永遠不會變啦!

python可變引數呼叫函式問題

一直使用python實現一些想法,近期在使用python的過程 現這樣乙個需求,定義了乙個函式。第乙個是普通引數。第二個是預設引數,後面還有可變引數,在最初學習python的時候,都知道非keyword可變引數和keyword可變引數兩種,呼叫的方式或許多種多樣,這裡主要提出乙個比較隱含的問題。並將...

python可變引數呼叫函式的問題

已使用python實現的一些想法,近期使用python這種出現的要求,它定義了乙個函式,第一種是一般的引數,第二個引數是預設,並有可變引數。在第一項研究中python時間,不知道keyword可變引數和keyword可變引數兩種,呼叫的方式或許多種多樣。這裡主要提出乙個比較隱含的問題。並將各種可能出...

Python 函式 可變引數

有些時候我們可能遇到引數的個數並不固定的情況,比如1 2 3 n 函式定義如下 def calc numbers sum 0 for n in numbers sum sum n n return sum上面這種情況只能傳乙個引數,而且引數一般是list或tuple,呼叫方式 calc 1,3,5 ...