位置参数解构的一个例子:
- In[23]: def fn(a, b, c):
- ...: print(a, b, c)
- ...:
- In[24]: lst = [1, 2, 3]
- In[25]: fn(lst[0], lst[1], lst[2])
- 1 2 3
- # 也可以进行如下形式的调用
- In[26]: fn(*lst) # 这种做法就叫参数解构
- 1 2 3
- # *号可以把线性结构解包成位置参数
- lst = [1, 2, 3, 4]
- fn(*lst) # -> fn(lst[0], lst[1], lst[2], lst[3])
- TypeError: fn() takes 3 positional arguments but 4 were given
# 这里就报错了,本来这个函数只能接收3个位置参数,lst有四个元素,通过参数解构之后,就变成了4个参数,所以就报错了。
接下来看字典解构的例子:
- In[27]: d = {'a': 1, 'b': 2, 'c': 3}
- In[28]: fn(**d)
- 1 2 3
- # **可以把字典解构成关键字参数
参数解构发生在函数调用时。解构的时候,线性结构的解构是位置参数,字典解构是关键字参数。
传参的顺序:位置参数,线性结构解构;关键字参数,字典解构。尽量的少的同时使用两种解构,除非你真的知道在做什么。
- In[29]: def fn(a, b, c, d):
- ...: print(a, b, c, d)
- ...:
- In[30]: fn(0, *[2], c=1, **{'d': 3})
- 0 2 1 3
9. 参数槽(keyword-only参数)
Python3中引入的。
- def fn(a, b, c):
- print(a, b, c)
- fn(a=1, b=2, c=3)
如果要强制传入的参数为关键字参数:
- def fn(*, a, b, c):
- print(a, b, c)
- >>> fn(1, 2, 3)
- Traceback (most recent call last):
- File "", line 1, in
- fn(1, 2, 3)
- TypeError: fn() takes 0 positional arguments but 3 were given
- >>> fn(a=1, b=2, c=3)
- 1 2 3
# *之后的参数,必须以关键字参数的形式传递,称之为参数槽。
参数槽通常和默认参数搭配使用。
- >>> def fn(a, b, *, x, y):
- print(a, b)
- print(x, y)
- >>> fn(1, 2, 3, 4)
- Traceback (most recent call last):
- File "", line 1, in
- fn(1, 2, 3, 4)
- TypeError: fn() takes 2 positional arguments but 4 were given
- >>> fn(1, 2, x=3, y=4)
- 1 2
- 3 4
- >>> fn(1, 2, **{'x': 3, 'y': 4})
- 1 2
- 3 4
- def fn(a, b, *):
- print(a, b)
- def fn(a, b, *):
- .. print(a, b)
- File "", line 1
- SyntaxError: named arguments must follow bare *
- 几个例子:
- def fn01(*, x=1, y=5):
- print(x)
- print(y)
- >>> fn01()
- 1
- 5
- def fn02(x=1, *, y):
- print(x)
- print(y)
- >>> fn02(y=3)
- 1
- 3
参数槽之坑:
*之后必须有参数非命名参数有默认值时,命名参数可以没有默认值默认参数应该在每段参数的最后使用参数槽时,不能使用可变位置参数,可变关键之参数必须放在命名参数之后
三、高级用法
1. 递归函数
在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。
- def fact(n):
- if n==1:
- return 1
- return n*fact(n-1)
使用递归函数的优点是逻辑简单清晰,缺点是过深的调用会导致栈溢出。
针对尾递归优化的语言可以通过尾递归防止栈溢出。尾递归事实上和循环是等价的,没有循环语句的编程语言只能通过尾递归实现循环。
2. 匿名函数 lambda
python 使用 lambda 来创建匿名函数。
lambda只是一个表达式,函数体比def简单很多。
lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
lambda函数拥有自己的名字空间,且不能访问自有参数列表之外或全局名字空间里的参数。 (编辑:辽源站长网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|