2013-05-09 71 views
2

我是Python的初學者,試圖理解函數參數及其類型和順序。試圖瞭解Python中的可選,列表和命名參數

我想嘗試用一下不同種說法,這裏是我的實驗

def main(): 
    test_a(2, 33, 44) 
    test_b(2, 33) 
    test_c(2) 
    ## test_d(2,,44) **Produces Invalid syntax** 

    test_e(2,33,44,55,66) 
    test_f(2, 44,55,66, y = 44) 

    test_g(2, 33, 44,55,66, rofa = 777, nard = 888) 
    ##test_h(2, 33, foo = 777, boo = 888, 44,55,66) **Invalid Syntax in Function definition 
    ##test_l(2, 44,55,66 , foo= 777, boo = 888, y = 900) **Invalid Syntax in Function definition 
    test_m(2, 44,55,66 , y = 900, foo=77777 , boo = 88888) 

############################################################# 
## NO optional arguments 
def test_a(x,y,z): 
    print("test_a : x = {}, y = {}, z = {} ".format(x ,y ,z)) 

## One optional argument at the end 
def test_b(x, y, z = 22): 
    print("test_b : x = {}, y = {}, z = {} ".format(x ,y ,z)) 

## TWO optional arguments at the end 
def test_c(x, y = 11, z = 22): 
    print("test_c : x = {}, y = {}, z = {} ".format(x ,y ,z)) 

## ONE optional argument at the middle 
## Produces Non-default argument follows default argument 
#### **** DEFAULT ARGUMENTS MUST COME AT THE END **** #### 
## def test_d(x, y = 11, z): 
## print("test_d : x = {}, y = {}, z = {} ".format(x ,y ,z)) 

################################################################# 

## NO optional argument + One List argument 
def test_e(x, y, *args): 
    print("test_e : x = {}, y = {} ||".format(x, y), end= " ") 
    for i in args : 
     print(i) 

## One optional argument + One list argument 
def test_f(x, *args , y = 5): 
    print("test_f : x = {}, y = {} ||".format(x, y), end= " ") 
    for i in args : 
     print(i) 

################################################################ 

## No optional argument, one list, one keyword arguments 
def test_g(x,y,*args, **kwargs): 
    print(x, y) 
    for i in args: 
     print(i) 

    for i, v in kwargs.items(): 
     print(i, v) 

## **kwargs befor *args produces syntax error !!! 
##def test_h(x,y, **kwargs, *args): 
## print(x, y) 
## for i in args: 
##  print(i) 
## 
## for i, v in kwargs.items(): 
##  print(i, v) 

## **kwargs befor optional argument produces syntax error !!! 
##def test_l(x,*args,**kwargs, y = 5): 
## print(x, y) 
## for i in args: 
##  print(i) 
## 
## for i, v in kwargs.items(): 
##  print(i, v) 
##  

## One optiona, list and keyword arguments 
def test_m(x,*args,y = 5, **kwargs): 
    print(x, y) 
    for i in args: 
     print(i) 

    for i, v in kwargs.items(): 
     print(i, v) 


if __name__ == "__main__": 
    main() 

我真正理解大部分的東西,這個實驗後。但有一個問題我不能進入我的腦海。

test_htest_m函數定義,其中**kwargs是可選的參數和list參數定義,當我運行該程序,即使我沒有使用該功能,只需定義它。它產生Syntax Error ..我感謝知道爲什麼會發生這種情況?

謝謝。

+3

'def'語句在代碼中到達時執行;如果您稍後調用該函數,則無關緊要。 (這是一個像其他任何聲明一樣)。 – geoffspear 2013-05-09 17:38:25

+2

不僅如此 - 整個腳本都會進行語法檢查,無論它是否可以執行。如果你做了'if False:!syntax_error',你仍然會得到一個語法錯誤,即使body不會被執行。 – bbayles 2013-05-09 17:41:48

回答

3

關鍵字參數必須傳遞給函數的最終參數。 Read up on it here.**kwargs這樣的參數必須是最後函數簽名中的參數(詳見文檔中的該頁)。從文檔:

當窗體的最終形式參數**名存在,則它接收一個字典(參見映射類型 - 字典)含有除那些對應於正式的參數的所有關鍵字參數。

代碼中引發了一個SyntaxError即使你不使用的功能是,如果違背這個規律,Python不能甚至完全因爲你想給它是簽名函數定義的原因非法。

+0

這正是我困惑的地方!當它說'它接收到一個包含所有關鍵字參數的字典,除了那些對應於正式參數的字典。「。現在我有用它的名字定義的'y = 5'可選參數。這是否被認爲是其他參數對應的鍵?即使它出現在** ** kwargs之後 – 2013-05-09 17:46:33

+0

@RafaelAdel這就是它的意思。 'test_m'運行得很好,至少在我的機器上。你確定你使用Python 3嗎?我相信'* args'在Python 3之前必須是'** kwargs'之外的最後一個參數,如果您運行的是Python 2,*會導致'test_m'引發錯誤。x – 2013-05-09 17:48:46

+2

@RafaelAdel:我認爲你在混合_parameters_和_arguments_。如果你有'def foo(a,b = 3)','a'是一個位置參數,'b'是一個具有默認值的位置參數。如果你用'foo(3,4)'調用它,'3'和'4'是位置參數。如果你用'foo(a = 5,b = 6)'調用它,那麼它們都是命名參數。但是它們仍然匹配相同的參數。所以,如果你'def foo(a,b = 3,** kw)',並且調用'foo(a = 5,b = 6)','b'是'對應於一個形式參數',因此doesn不會以'kw'結尾。 – abarnert 2013-05-09 17:50:13

1

*args**kwargs必須是指定的最後一個參數(按該順序!);原因在於它們本質上是「catch-alls」,它們匹配傳遞給函數的參數,這些參數與預先列出的特定參數不匹配,所以在特定參數之前列出它們是不明確的。

例如,上面test_m必須被指定爲

def test_m(x, y=5, *args, **kwargs): 
    ... 
+2

這對於'* args'來說並不是真的。您可以在函數簽名中儘早使用它,但是除非將它們作爲關鍵字參數引用,否則不能使用以下任何參數調用該函數。 [看這裏的例子。](http://docs.python.org/3/tutorial/controlflow.html#arbitrary-argument-lists) – 2013-05-09 17:46:07

+1

(這是Python 3的新功能,但問題被標記爲這樣.. ) – geoffspear 2013-05-09 17:46:56