Python学习笔记(十七)- 参数( Arguments)

在大多数下面的问题中,结果可能在 2.X 中略有不同 - 在打印多个值时用括号和逗号括起来。 要在 2.X 中完全匹配 3.X 的答案,请在开始之前从  __future__ 导入 print_function (from __future__ import print_function)。


1.以下代码的输出是什么,为什么?

>>> def func(a, b=4, c=5):
        print(a, b, c)
>>> func(1, 2)

答:此处的输出为1 2 5,因为1和2按位置(by position 位置参数)传递给 a 和 b,并且调用中省略了c,没有传入c的值,所以默认为5。

 

2.以下代码的输出是什么,为什么?

>>> def func(a, b, c=5):
         print(a, b, c)
>>> func(1, c=3, b=2)

答:此次输出为 1 2 3:1按位置被传递(位置参数),并b和c以名字传值2和3(关键字参数)(从左到右的顺序在关键字参数时无关紧要)

 

3.那下面的代码呢:它的输出是什么,为什么?

>>> def func(a, *pargs):
         print(a, pargs)
>>> func(1, 2, 3)

答:此代码打印1(2,3),因为 1 传递给a 并且 * pargs将剩余的位置参数收集到新的元组对象中。我们可以使用任何迭代工具逐步执行额外的位置参数元组(例如,for arg in pargs:...)。

 

4.下面的代码打印什么,为什么?

>>> def func(a, **kargs):
         print(a, kargs)
>>> func(a=1, c=3, b=2)

答:这次代码打印1 {'b':2,'c':3},因为 1 以名称传递给 a,** kargs将剩余的关键字参数收集到一个字典中。我们可以使用任何迭代工具按键逐步执行额外的关键字参数字典(例如,for key in kargs:...)。请注意,字典键的顺序可能因Python和其他变量而异。

 

5.这段代码打印什么,为什么?

>>> def func(a, b, c=3, d=4): 
        print(a, b, c, d)
>>> func(1, *(5, 6))

答:这里的输出是1 5 6 4:1 按位置匹配,5 和 6 的元组由 *name 解包成为 5 和 6 按位置分别匹配 b 和 c(6覆盖 c 的默认值),d 默认为4,因为它没有传递一个值。

 

6.最后一次:这段代码的输出是什么?为什么?

>>> def func(a, b, c): a = 2; b[0] = 'x'; c['a'] = 'y'
>>> l=1; m=[1]; n={'a':0}
>>> func(l, m, n)
>>> l, m, n

答:这会显示(1,['x'],{'a':'y'}) - 函数中的第一个赋值不影响调用时传入的 l,但后两个分配有影响,因为它们更改了传入的可变对象。

一些粗糙的细节

参数传递时的排序顺序

1.函数调用(function call):位置参数(positional arguments)=> 关键字参数(keyword arguments)=> *iterable => **dict

2.函数头部(function header):正常参数(normal arguments)=> 默认参数(default arguments)=> *name => **dict

内部实现匹配参数:

1.按位置分配无关键字参数

2.按匹配名字分配关键参数

3.把额外的关键字参数赋给 *name 元组

4.把默认值赋给为赋值的参数(在头部)

之后,Python会检查是否所有参数都赋值,发现没有,抛出异常。

 

一些例子:

#1.
>>> def f(a, *b, **d, c=6): print(a, b, c, d) # 强制关键字参数(Keyword-only) 在 ** 之前!
SyntaxError: invalid syntax

>>> def f(a, *b, c=6, **d): print(a, b, c, d) # 在函数头部收集参数
#在有 *b 和 **d出现时,强制关键字参数只能放它们中间

>>> f(1, 2, 3, x=4, y=5) # 使用默认值
1 (2, 3) 6 {'y': 5, 'x': 4}

>>> f(1, 2, 3, x=4, y=5, c=7) # 覆写默认值
1 (2, 3) 7 {'y': 5, 'x': 4}

>>> f(1, 2, 3, c=7, x=4, y=5) # 在任何地方的关键字参数,指的应该是关键字c的位置
1 (2, 3) 7 {'y': 5, 'x': 4}

#2.
>>> def f(a, c=6, *b, **d): print(a, b, c, d) # c在这里不是强制关键字参数(keyword-only)!

>>> f(1, 2, 3, x=4)
1 (3,) 2 {'x': 4}

#3.
>>> def f(a, *b, c=6, **d): print(a, b, c, d) # 强制关键字参数 在 * 和 ** 中间出现

>>> f(1, *(2, 3), **dict(x=4, y=5)) # 在调用时解包(unpack)
1 (2, 3) 6 {'y': 5, 'x': 4}

>>> f(1, *(2, 3), **dict(x=4, y=5), c=7) # 在 **args 之前的关键字,应该指的是函数c中的位置!
SyntaxError: invalid syntax

>>> f(1, *(2, 3), c=7, **dict(x=4, y=5)) # 覆写默认值
1 (2, 3) 7 {'y': 5, 'x': 4}

>>> f(1, c=7, *(2, 3), **dict(x=4, y=5)) # 在 * 之前或之后
1 (2, 3) 7 {'y': 5, 'x': 4}

>>> f(1, *(2, 3), **dict(x=4, y=5, c=7)) # 强制关键字参数 在 ** 中
1 (2, 3) 7 {'y': 5, 'x': 4}

备注:可能理解上有些问题,代码是对的 (*^▽^*)

 

标注:转载《Learning Python 5th Edition》[奥莱理]

In most of this quiz’s questions, results may vary slightly in 2.X—with enclosing parentheses and commas when multiple values are printed. To match the 3.X answers exactly
in 2.X, import print_function from __future__ before starting.
1. What is the output of the following code, and why?

>>> def func(a, b=4, c=5):
         print(a, b, c)
>>> func(1, 2)


2. What is the output of this code, and why?

>>> def func(a, b, c=5):
         print(a, b, c)
>>> func(1, c=3, b=2)


3. How about this code: what is its output, and why?

>>> def func(a, *pargs):
         print(a, pargs)
>>> func(1, 2, 3)


4. What does this code print, and why?

>>> def func(a, **kargs):
         print(a, kargs)
>>> func(a=1, c=3, b=2)


5. What gets printed by this, and why?

>>> def func(a, b, c=3, d=4): print(a, b, c, d)
>>> func(1, *(5, 6))


6. One last time: what is the output of this code, and why?

>>> def func(a, b, c): a = 2; b[0] = 'x'; c['a'] = 'y'
>>> l=1; m=[1]; n={'a':0}
>>> func(l, m, n)
>>> l, m, n


1. The output here is 1 2 5, because 1 and 2 are passed to a and b by position, and c is omitted in the call and defaults to 5.
2. The output this time is 1 2 3: 1 is passed to a by position, and b and c are passed 2 and 3 by name (the left-to-right order doesn’t matter when keyword arguments are used like this).
3. This code prints 1 (2, 3), because 1 is passed to a and the *pargs collects the remaining positional arguments into a new tuple object. We can step through the extra positional arguments tuple with any iteration tool (e.g., for arg in pargs: ...).
4. This time the code prints 1 {'b': 2, 'c': 3}, because 1 is passed to a by name and the **kargs collects the remaining keyword arguments into a dictionary. We could step through the extra keyword arguments dictionary by key with any iteration tool (e.g., for key in kargs: ...). Note that the order of the dictionary's keys may vary per Python and other variables.
5. The output here is 1 5 6 4: the 1 matches a by position, 5 and 6 match b and c by *name positionals (6 overrides c’s default), and d defaults to 4 because it was not passed a value.
6. This displays (1, ['x'], {'a': 'y'})—the first assignment in the function doesn’t impact the caller, but the second two do because they change passed-in mutable objects in place.

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值