关键字参数:函数调用时,在实参前面指定形参名的方式。即决定参数是否是关键字参数的是实参,跟形参没有关系。
带有默认值的参数:定义函数时,形参给定默认值。是否为带有默认值的参数是由形参决定的,跟实参没有关系。此时若调用函数时,直接传入实参而没有在实参前指定形参名的话,就只是位置参数;如果调用函数时,实参前指定了形参名,就是关键字参数。
位置参数的形参可以指定默认值,关键字参数的形参也可以指定默认值,即是否制定默认值,跟是否是什么类型的参数无关。
函数的参数有四种:非关键字参数、非关键字收集参数、关键字参数、关键字收集参数。非关键字参数和非关键字收集参数称为位置参数,因为这样的参数的位置至关重要。
参数收集:
非关键字收集参数(*args):当非关键字参数的个数不确定时,其他的参数可以通过*args以元组的形式由args收集起来。
>>> def func(x, *args): ... print('x=%s'%x) ... print('args={}'.format(args)) # 多余的参数*args以元组的形式由args收集起来 ... >>> func(1, 2, 3, 4, 5, 6, 7) x=1 args=(2, 3, 4, 5, 6, 7) # 值2, 3, 4, 5, 6, 7被塞入一个元组里传给了args
即使只有一个值,也要用元组收集它。
>>> def func(x, *args): ... print('x=%s'%x) ... print('args={}'.format(args)) ... >>> func(1, 2) x=1 args=(2,) # 只有一个值,也要用元组收集
不给*args传值也是允许的,这时args收集到的是一个空元组。
>>> def func(x, *args): ... print('x=%s'%x) ... print('args={}'.format(args)) ... >>> func(1) x=1 args=() # args收集到的是一个空元组
关键字收集参数(**kwargs):当关键字参数的个数不确定时,其他的参数可以通过**kwargs以字典的形式由kwargs收集起来。
>>> def func(**kwargs): ... print('kwargs={}'.format(kwargs)) ... >>> func(a=1, b=2, c=3) # 必须传入关键字参数 kwargs={'a': 1, 'c': 3, 'b': 2} # 以字典的形式收集起来
用**kwargs的形式收集参数,会得到字典类型的数据,必须在传值的时候说明“键”和“值”,即传入关键字参数。
混合传参:四种参数传入的方式组合起来。但是,必须按照固定的顺序——所有的位置参数要在所有的关键字参数前面;带默认值的形参在不带默认值的形参后面;同为位置参数时,收集参数要放在最后面;同位关键字参数时,收集参数放最后面。即不带默认值的非关键字参数、带默认值的非关键字参数、非关键字收集参数、关键字参数、关键字收集参数。
>>> def func(x, *args, y=2, **kwargs): ... print('x=%s'%x) ... print('args={}'.format(args)) ... print('y=%s'%y) ... print('kwargs={}'.format(kwargs)) ... >>> func(33, 66, 77, y=99, lang='python') # 混合传参必须按照固定的顺序 x=33 args=(66, 77) y=99 kwargs={'lang': 'python'}
分配参数:运算符(*和**)不仅可以在定义函数的时候,作为函数的收集参数;也可以在调用函数的时候,作为函数的分配参数,即执行与定义函数时相反的操作。
通过*将元组中(或列表)的参数分配给函数的形参:
>>> def add(x, y, z): ... return x + y + z ... >>> params = (2, 5 ,7) # 参数是元组 >>> add(*params) # 参数分配 14
通过**将字典中的参数分配给函数的形参:
>>> def hello(name, greeting): ... print(greeting, name) ... >>> params = {'name':'Jack', 'greeting':'Hello'} # 参数是字典 >>> hello(**params) # 分配参数 Hello Jack
函数的文档:包含函数的作用;函数的参数介绍(参数的个数和数据类型);函数的返回值(数据和类型)。
函数返回(结束):函数调用结束后将返回到被调用处。然后继续向下执行。
题目:编写一个模仿range()的函数。
>>> def interval(start, stop=None, step=1): ... 'Imitates range() for step > 0' ... if stop is None: ... start, stop = 0, start ... result = [] ... i = start ... while i < stop: ... result.append(i) ... i += step ... return result ... >>> interval(10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> interval(1, 10, 2) [1, 3, 5, 7, 9]