重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
Python函数的参数是什么?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。
创新互联是创新、创意、研发型一体的综合型网站建设公司,自成立以来公司不断探索创新,始终坚持为客户提供满意周到的服务,在本地打下了良好的口碑,在过去的十多年时间我们累计服务了上千家以及全国政企客户,如宴会酒店设计等企业单位,完善的项目管理流程,严格把控项目进度与质量监控加上过硬的技术实力获得客户的一致称赞。
函数的灵活性非常高,除了常规定义的位置参数以外,还支持默认参数、关键字参数、以及可变参数 ... 这样以来,不但能应对各种复杂的情况,甚至还可以简化调用者的代码。
位置参数
在调用函数时,一般会根据函数定义的参数位置来传递参数,这样的参数叫做位置参数。
考虑下面的例子,函数包含了两个参数 - name 和 msg:
>>> def greet(name, msg): ... print('Hello, {}, {}!'.format(name, msg)) ...>>>
调用它很容易:
>>> greet('Pony', 'nice to meet you') Hello, Pony, nice to meet you!
这里,值会按照顺序被依次分配。由于“Pony”是第一个值,所以它会被分配给第一个参数 name;同样地,“nice to meet you”会被分配给第二个参数 msg。
当传递两个值时,函数运行地很顺利。但倘若参数的个数不匹配,会发生什么?
>>> greet('Pony') # 少一个参数 ... TypeError: greet() missing 1 required positional argument: 'msg'
显然,解释器会发牢骚。但对 Python 来说,要解决这个问题简直是易如反掌,继续往下看!
默认参数
在定义函数时,可以使用赋值运算符(=)为参数指定默认值:
>>> def greet(name, msg = 'nice to meet you'): ... print('Hello, {}, {}!'.format(name, msg)) ... >>>
注意: 如果参数没有默认值,在调用函数时必需为其指定一个值;如果有默认值,那么在调用时值是可选的,如果为其提供了一个值,将会覆盖默认值。
由于 name 没有默认值,所以必须指定值,而 msg 有默认值,所以值是可选的:
>>> greet('Pony') # 使用默认值 Hello, Pony, nice to meet you! >>> >>> greet('Pony', 'give me a hug') # 覆盖默认值 Hello, Pony, give me a hug!
值得注意的是,函数中的所有参数都可以有默认值,但是一旦存在一个默认参数,其右侧的所有参数也必须有默认值。
也就是说,非默认参数不能在默认参数之后。例如,像下面这样,就会报错:
>>> def greet(msg = 'nice to meet you', name): ... print('Hello, {}, {}!'.format(name, msg)) ... File "", line 1 SyntaxError: non-default argument follows default argument
关键字参数
为方便起见,Python 还允许使用 key = value 形式的关键字参数调用函数:
>>> def greet(name, msg): ... print('Hello, {}, {}!'.format(name, msg)) ...>>>
当以这种方式调用函数时,所有传递的关键字参数都必须与函数接受的某个参数匹配,并且它们的顺序不重要:
>>> greet(name = 'Pony', msg = 'nice to meet you') # 按循序传递 Hello, Pony, nice to meet you! >>> >>> greet(msg = 'nice to meet you', name = 'Pony') # 顺序颠倒也可以 Hello, Pony, nice to meet you!
此外,它还可以和位置参数混合使用,但关键字参数必须在位置参数之后:
>>> greet('Pony', msg = 'nice to meet you') # 位置参数与关键字参数混合使用 Hello, Pony, nice to meet you!
所以,如果像下面这样调用,就会报错:
>>> greet(name = 'Pony', message = 'nice to meet you') # message 不存在 ... TypeError: greet() got an unexpected keyword argument 'message' >>> >>> greet(msg = 'nice to meet you', 'Pony') # 关键字参数不能在位置参数之前 ... SyntaxError: positional argument follows keyword argument
可变参数
可变参数也被称为不定长参数,顾名思义,就是传入的参数个数是可变的,可以是任意多个(0、1、2 ...)。``
包裹位置传递
在参数名之前可以添加一个星号(*),在函数内部,所有传入的参数都会被变量 names 收集,最终按照位置将它们合并为一个元组:
>>> def greet(*names): ... print('Hello,', names) ... >>>
尝试一下,传递不同个数的参数:
>>> greet() # 没有参数,为空元组 Hello, () >>> >>> greet('Pony') Hello, ('Pony',) >>> >>> greet('Jack Ma', 'Pony') Hello, ('Jack Ma', 'Pony')
通常情况下,可变参数(*)会出现在形参列表的最后,因为它们会把传递给函数的所有剩余输入参数都收集起来:
>>> def greet(msg, *names): ... print('Hello, {}, {}!'.format(names, msg)) ... >>> >>> greet('nice to meet you', 'Jack Ma', 'Pony') Hello, ('Jack Ma', 'Pony'), nice to meet you!
话虽如此,但可变参数(*)之后还可以出现其它参数,只不过这些形参都是“强制关键字”参数,这意味着,它们只能被用作关键字参数,而不能是位置参数:
>>> def greet(*names, msg): ... print('Hello, {}, {}!'.format(names, msg)) ... >>> >>> greet('Pony', msg = 'nice to meet you') # 只能被用作关键字参数 Hello, ('Pony',), nice to meet you! >>> >>> greet(msg = 'nice to meet you', 'Pony') # 不能被用作位置参数 ... SyntaxError: positional argument follows keyword argument
包裹关键字传递
还有一种机制,在参数名之前添加两个星号(**),当这种形式出现时,msgs 将收集所有关键字参数,最终将它们合并为一个字典:
>>> def greet(**msgs): ... print('Hello,', msgs) ...>>>
和上面一样,尝试传递不同个数的参数:
>>> greet() # 没有参数,为空字典 Hello, {} >>> >>> greet(name = 'Pony') Hello, {'name': 'Pony'} >>> >>> greet(name = 'Pony', msg = 'nice to meet you') Hello, {'name': 'Pony', 'msg': 'nice to meet you'}
此外,*names 还可以与 **msgs 形式的参数相结合,但*names 必须出现在 **msgs 之前。
例如,像下面这样,就会报错:
>>> def greet(**msgs, *name): ... SyntaxError: invalid syntax
解包裹参数
正如【可变参数】那样,也可在函数调用中使用 * 和 **。只不过在这种情况下,与在函数定义中的语义相反,参数将被解包裹而不是被包裹:
>>> def greet(name, msg): ... print('Hello, {}, {}!'.format(name, msg)) ... >>>
尝试一下,元组用 * 来传递位置参数:
>>> t = ('Pony', 'nice to meet you') >>> greet(*t) Hello, Pony, nice to meet you!
同样地,字典也可以用 ** 传递关键字参数:``
>>> d = {'name':'Pony', 'msg':'nice to meet you'} >>> greet(**d) Hello, Pony, nice to meet you!
位置参数、默认参数、可变参数混合使用
根据上面的介绍,我们不难发现,当这些参数混合使用时,应遵循一个基本的原则:位置参数 -> 默认参数 -> 包裹位置 -> 包裹关键字(定义和调用都应遵循该顺序)。
例如,定义一个函数,能够同时向多个人发送多条消息:
>>> def greet(sender, address = 'BeiJing', *receivers, **msgs): ... print('Hello, I am {}, from {}.'.format(sender, address)) ... print('-' * 30) # 华丽的分割线 ... for rec in receivers: ... for key, val in msgs.items(): ... print('No {}: {}, {}!'.format(key, val, rec)) ... print('-' * 30) # 华丽的分割线 ... >>>
为了显示更好的效果,我们在中间穿插了一些华丽的分割线:
>>> greet('Waleon', 'Xi\'an', 'Jack Ma', 'Pony', one = 'nice to meet you', two = 'give me a hug') Hello, I am Waleon, from Xi'an. ------------------------------ No one: nice to meet you, Jack Ma! No two: give me a hug, Jack Ma! ------------------------------ No one: nice to meet you, Pony! No two: give me a hug, Pony! ------------------------------
看完上述内容,你们掌握Python函数的参数是什么的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注创新互联行业资讯频道,感谢各位的阅读!