Function Definition Playground
运行下面的单元格,看看它们会不会报错。
默认参数
python
def func1(a, b, c):
'''非常普通的函数'''
pass
1
2
3
2
3
python
def func2(a, b, c=0):
"""非常普通的带默认参数的函数"""
pass
1
2
3
2
3
python
def func3(a=0, b, c):
'''默认参数放在了必需参数前面的函数'''
pass
1
2
3
2
3
Cell In[3], line 1
def func3(a=0, b, c):
^
SyntaxError: non-default argument follows default argument
1
2
3
4
2
3
4
↑ 默认参数必须放在必需参数后。
python
func2(1, 2, 3) # 正确的,一般的默认参数也能接收位置参数
func2(1, 2, c=0) # 正确的,一般的默认参数也能接收关键字参数
func2(1, c=0, b=0) # 正确的,关键字参数可以调换位置
func2(a=1, 2, 3) # 错误的,关键字参数必须放在位置参数后
1
2
3
4
2
3
4
Cell In[29], line 4
func2(a=1, 2, 3) # 错误的,关键字参数必须放在位置参数后
^
SyntaxError: positional argument follows keyword argument
1
2
3
4
2
3
4
仅位置参数分隔符
3.8+
only
python
def func4(a, /, b, c):
'''
带有仅位置参数的函数
`/` - 仅位置参数符,在它前面的都是仅位置参数(3.8+)
'''
pass
1
2
3
4
5
6
7
2
3
4
5
6
7
python
func4(1, 2, c=3) # 正确的
func4(a=1, b=2, c=3) # 错误的,因为`a`不能被关键字调用。
1
2
2
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[16], line 2
1 func4(1, 2, c=3) # 正确的
----> 2 func4(a=1, b=2, c=3) # 错误的,因为`a`不能被关键字调用。
TypeError: func4() got some positional-only arguments passed as keyword arguments: 'a'
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
python
def func5(a, /, b, /, c):
'''带有多个`/`符的函数'''
pass
1
2
3
2
3
Cell In[5], line 1
def func5(a, /, b, /, c):
^
SyntaxError: / may appear only once
1
2
3
4
2
3
4
↑ /
只能出现一次
仅限关键字参数分隔符 & 任意数量位置参数
可以将前者看作是后者的特化版本。
python
def func6(a, b, *args, c):
'''带有任意数量位置参数(使用`*`标记)的函数'''
pass
1
2
3
2
3
python
func6(1, 2, 3, 4, 5, 6, 7, 8, c=10) # 正确的,3~8都被收进了`args`中
# 显然由于`args`接收任意数量的位置参数,若不通过关键字传参,`c`永远也收不到值
func6(1, 2, c=10) # 正确的,此时`args`为空元组
func6(1, 2, 3, 4, 5, 6, 7, 8, 10) # 错误的,试图向`*`符后方的`c`传递位置参数
1
2
3
4
2
3
4
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[21], line 4
2 # 显然由于`args`接收任意数量的位置参数,若不通过关键字传参,`c`永远也收不到值
3 func6(1, 2, c=10) # 正确的,此时`args`为空元组
----> 4 func6(1, 2, 3, 4, 5, 6, 7, 8, 10) # 错误的,试图向`*`符后方的`c`传递位置参数
TypeError: func6() missing 1 required keyword-only argument: 'c'
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
python
def func7(a, b, *args, *args_):
'''试图在参数列表中使用多个`*`的函数'''
pass
1
2
3
2
3
Cell In[9], line 1
def func7(a, b, *args, *args_):
^
SyntaxError: * argument may appear only once
1
2
3
4
2
3
4
↑ *
也只能出现一次
python
def func8(a, b, *, c):
'''
将多出来的位置参数全部丢掉的函数(省略了用于接收多余位置实参的那个形参)
此时`*`只起到限制位置传参的作用,被称为仅限关键字参数分隔符,与`/`相对应
'''
pass
1
2
3
4
5
6
2
3
4
5
6
python
func8(1, 2, c=3) # 正确的
func8(1, 2, 3) # 错误的,试图向`*`符后方的`c`传递位置参数
1
2
2
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[15], line 2
1 func8(1, 2, c=3) # 正确的
----> 2 func8(1, 2, 3) # 错误的,试图向`*`符后方的`c`传递位置参数
TypeError: func8() takes 2 positional arguments but 3 were given
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
↑ 注意看这里报错信息不一样的,所以它们还是不能完全等同
—— 但是这样理解也是没错的喵 w
任意数量关键字参数
python
def func9(a, b, c, **kwargs):
'''带有任意数量关键字参数的函数
`**kwargs`将收集所有无法与前面所有参数匹配的关键字参数
'''
pass
1
2
3
4
5
2
3
4
5
python
func9(1, 2, 3, d=4) # 正确的,`kwargs`中`"d"`对应的键将会是`4`
func9(1, 2, 3) # 正确的,此时`kwargs`为空字典
func9(1, 2, c=3, d=4) # 正确的,`c`在到达`**kwargs`前就已经被匹配了。
func9(1, 2, 3, c=4) # 错误的,相当于对`c`多传了一个值
1
2
3
4
2
3
4
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[24], line 4
2 func9(1, 2, 3) # 正确的,此时`kwargs`为空字典
3 func9(1, 2, c=3, d=4) # 正确的,`c`在到达`**kwargs`前就已经被匹配了。
----> 4 func9(1, 2, 3, c=4)
TypeError: func9() got multiple values for argument 'c'
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
python
def func10(a, b, **kwargs, c):
'''
试图将任意数量关键字参数放在任意参数前的函数
这意味着如果存在任意数量关键字参数,它一定会在参数列表最后
'''
pass
1
2
3
4
5
6
2
3
4
5
6
Cell In[17], line 1
def func10(a, b, **kwargs, c):
^
SyntaxError: arguments cannot follow var-keyword argument
1
2
3
4
2
3
4
python
def func11(a, b, **kwargs, **kwargs_):
'''
试图接收多个任意数量关键字参数的函数
'''
pass
1
2
3
4
5
2
3
4
5
Cell In[23], line 1
def func11(a, b, **kwargs, **kwargs_):
^
SyntaxError: arguments cannot follow var-keyword argument
1
2
3
4
2
3
4
让我们把所有元素放到一起
这话听上去怪耳熟的,怎么秽蚀呢
python
def func12(
pos1, pos2, # 仅限位置参数
/, # 仅限位置参数分隔符
pos_or_kw, # 位置或关键字参数 / 普通参数
*, # 仅限关键字参数分隔符
kw1, kw2, # 仅限关键字参数
**kwargs # 任意数量关键字参数
):
pass
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
python
func12(1, 2, 3, kw1=4, kw2=5, extra=6)
# 正确的
# 仅限位置参数得到了位置参数,
# 普通参数得到了一个位置参数
# 仅限关键字参数得到了关键字参数,
# 任意数量关键字参数得到了一个关键字参数,
# 我们都有光明的未来(喜)
1
2
3
4
5
6
7
2
3
4
5
6
7
python
func12(1, 1, 4, 5, 1, 4, 1, 9, 1, 9)
# 试图仅以位置参数囊括全部的池沼调用(恼)
1
2
2
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[27], line 1
----> 1 func12(1, 1, 4, 5, 1, 4, 1, 9, 1, 9)
2 # 试图仅以位置参数囊括全部的池沼调用
TypeError: func12() takes 3 positional arguments but 10 were given
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10