2013-05-09 70 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