Python函数传参规则详解

最近学校的期中考试考到了这点,所以我简单的把教授的笔记整理翻译一下。

当函数被调用时,python会先将Arguments与Parameters一一绑定,然后执行函数内容。

(译者注:parameters指函数定义头部的参数模版,arguments是调用函数时所给的参数。)

Arguments:
位置形参数:指没有被制定名称(name=value)的参数
命名形参数:指被指定名称的参数
Parmeters:
未指定值模版:只有名称,没有默认值的参数
指定值模版:指定了默认值的参数

当python函数被调用时,python必须一一绑定所有函数头模版与传入参数,否则将会报错。
下面是参数绑定的规则。规则必须按顺序执行,因此,当我们执行到M3时,无法再根据M1绑定参数。

M1.绑定所有位置形参数到函数头模版中(无论是否指定默认值),在遇到任何命名形参数或形参(*args)时停止这条规则。
M2.当绑定形参时,将所有剩下的位置形参数绑定此形参。Python会创建一个元组来储存这些参数。
M3.绑定所有命名形参数到函数头模版中(根据他们的名称,且不论是否指定默认值)
M4.如果还剩下一些头参数模版没有绑定,绑定所有模版中的默认值。
M5.抛出异常(Exceptions):在任意时刻,如果a.参数无法匹配到模版(比如一个位置形参数在命名形参数后面出现)或b.一个模版被匹配了多个参数以及c.任何一个模版没有被匹配参数d.任何一个参数没有被匹配到模版,抛出异常。情况a则抛出SyntaxError,情况b,c,d抛出TypeError

特别的,当我们遇到**kargs时,python会执行完M4规则后,再将所有剩余的键值对绑定在kargs字典中。

下面是一些例子:

def f(a,b,c=10,d=None): print(a,b,c,d)
def g(a=10,b=20,c=30) : print(a,b,c)
def h(a,*b,c=10)      : print(a,b,c)
Call              | Parameter/Argument Binding (matching rule)
------------------+--------------------------------------------
f(1,2,3,4)	  | a=1, b=2, c=3, d=4(M1)
f(1,2,3)	  | a=1, b=2, c=3(M1); d=None(M4)
f(1,2)		  | a=1, b=2(M1); c=10, d=None(M4)
f(1)		  | a=1(M1); c=10, d=None(M4);
                       TypeError(M5c: parameter b not matched)
f(1,2,b=3) 	  | a=1, b=2(M1); b=3(M3); c=10, d=None(M4)
                      TypeError(M5b: parameter b matched twice)
f(d=1,b=2)	  | d=1, b=2(M3); c=10(M4);
                       TypeError(M5c: parameter a not matched)
f(b=1,a=2)	  | b=1, a=2(M3); c=10, d=None(M4)
f(a=1,d=2,b=3)	  | a=1, d=2, b=3(M3); c=10(M4)
f(c=1,2,3)	  | c=1(M3);
                       SyntaxError(M5a:2 is positional argument)

g()		  | a=10, b=20, c=30(M4)
g(b=1)		  | b=1(M3); a=10, c=30(M4)
g(a=1,2,c=3)	  | a=1(M3);
                       SyntaxError(M5a:2 is positional argument)

h(1,2,3,4,5)	  | a=1(M1); b=(2,3,4,5)(M2), c=10(M4)
h(1,2,3,4,c=5)    | a=1(M1); b=(2,3,4)(M2), c=5(M3)
h(a=1,2,3,4,c=5)  | a=1(M3);
                       SyntaxError(M5a:2 is positional argument))
h(1,2,3,4,c=5,a=1)| a=1(M1); b=(2,3,4)(M2); c=5(M3);
                        TypeError(M5b:a matched twice)

然后是我们的考试题,非常令人发指:

When a function is called, Python performs two main actions; what are they?
答案:1. Binding arguments to parameters. 2. Execute function body.

Gvien the function definition
def f(a,*args,y=None,**kargs):
    print(a,args,y,kargs)

What does the legal call(1,2,3,x='a',y='b',z='c') print? If it raises an exceptions, specify which.

解:看到这种题手里还没电脑确实有点慌,但我们按规则一条条来。
M1: 匹配位置形参数: 1 -> a 因为遇到了*args,停止这条规则
M2: 匹配形参,绑定所有位置形参数: 2->args 3->args
M3: 绑定所有的命名形参数: ‘b’ -> y
M4: 绑定没有被绑定对默认模版:这里面没有,跳过
绑定字典参数 x=‘a’,z=‘c’
M5: 未发现异常,所有参数与模版均已绑定
输出
1 (2,3) b {x:‘a’,z:‘c’}
答案:1 (2,3) b {x:‘a’,z:‘c’}

希望帮到大家

你可能感兴趣的:(Translations)