13、函数的参数
一 形参与实参介绍
函数的参数分为形式参数和实际参数,简称形参和实参:
形参即在定义函数时,括号内声明的参数。形参本质就是一个变量名,用来接收外部传来的值。
实参即在调用函数时,括号内传入的值,值可以是常量、变量、表达式或三者的组合:
在调用有参函数时,实参(值)会赋值给形参(变量名)。在Python中,变量名与值只是单纯的绑定关系,而对于函数来说,这种绑定关系只在函数调用时生效,在调用结束后解除。
二 形参与实参的具体使用
2.1 位置参数
位置即顺序,位置参数指的是按顺序定义的参数,需要从两个角度去看:
-
在定义函数时,按照从左到右的顺序依次定义形参,称为位置形参,凡是按照这种形式定义的形参都必须被传值
-
在调用函数时,按照从左到右的顺序依次定义实参,称为位置实参,凡是按照这种形式定义的实参会按照从左到右的顺序与形参一一对应
2.2 关键字参数
在调用函数时,实参可以是key=value的形式,称为关键字参数,凡是按照这种形式定义的实参,可以完全不按照从左到右的顺序定义,但仍能为指定的形参赋值
需要注意在调用函数时,实参也可以是按位置或按关键字的混合使用,但必须保证关键字参数在位置参数后面,且不可以对一个形参重复赋值
2.3 默认参数
在定义函数时,就已经为形参赋值,这类形参称之为默认参数,当函数有多个参数时,需要将值经常改变的参数定义成位置参数,而将值改变较少的参数定义成默认参数。例如编写一个注册学生信息的函数,如果大多数学生的性别都为男,那完全可以将形参sex定义成默认参数
定义时就已经为参数sex赋值,意味着调用时可以不对sex赋值,这降低了函数调用的复杂度
需要注意:
- 默认参数必须在位置参数之后
- 默认参数的值仅在函数定义阶段被赋值一次
-
默认参数的值通常应设为不可变类型
每次调用是在上一次的基础上向同一列表增加值,修改如下
2.4 可变长度的参数(*与**的用法)
参数的长度可变指的是在调用函数时,实参的个数可以不固定,而在调用函数时,实参的定义无非是按位置或者按关键字两种形式,这就要求形参提供两种解决方案来分别处理两种形式的可变长度的参数
2.4.1 可变长度的位置参数
如果在最后一个形参名前加 * 号,那么在调用函数时,溢出的位置实参,都会被 * 接收,以元组的形式保存下来赋值给该形参
如果我们事先生成了一个列表,仍然是可以传值给 * args的
注意:如果在传入L时没有加 * ,那L就只是一个普通的位置参数了
如果形参为常规的参数(位置或默认),实参仍可以是 * 的形式
如果我们想要求多个值的和,* args就派上用场了
2.4.2 可变长度的关键字参数
如果在最后一个形参名前加 ** 号,那么在调用函数时,溢出的关键字参数,都会被 ** 接收,以字典的形式保存下来赋值给该形参
如果我们事先生成了一个字典,仍然是可以传值给 ** kwargs的
注意:如果在传入dic时没有加 ** ,那dic就只是一个普通的位置参数了
如果形参为常规参数(位置或默认),实参仍可以是 ** 的形式
如果我们要编写一个用户认证的函数,起初可能只基于用户名密码的验证就可以了,可以使用 ** kwargs为日后的扩展供良好的环境,同时保持了函数的简洁性。
2.5 命名关键字参数
在定义了 ** kwargs参数后,函数调用者就可以传入任意的关键字参数key=value,如果函数体代码的执行需要依赖某个key,必须在函数内进行判断
想要限定函数的调用者必须以key=value的形式传值,Python3提供了专门的语法:需要在定义形参时,用 * 作为一个分隔符号,* 号之后的形参称为命名关键字参数。对于这类参数,在函数调用时,必须按照key=value的形式为其传值,且必须被传值
命名关键字参数也可以有默认值,从而简化调用
需要强调的是:sex不是默认参数,height也不是位置参数,因为二者均在* 后,所以都是命名关键字参数,形参sex=’male’属于命名关键字参数的默认值,因而即便是放到形参height之前也不会有问题。另外,如果形参中已经有一个* args了,命名关键字参数就不再需要一个单独的*作为分隔符号了
2.6 组合使用
综上所述所有参数可任意组合使用,但定义顺序必须是:位置参数、默认参数、* args、命名关键字参数、** kwargs
可变参数 * args与关键字参数 ** kwargs通常是组合在一起使用的,如果一个函数的形参为 * args与 ** kwargs,那么代表该函数可以接收任何形式、任意长度的参数
在该函数内部还可以把接收到的参数传给另外一个函数(这在4.6小节装饰器的实现中大有用处)
按照上述写法,在为函数wrapper传参时,其实遵循的是函数func的参数规则,调用函数wrapper的过程分析如下:
- 位置实参1被*接收,以元组的形式保存下来,赋值给args,即args=(1,),关键字实参z=3,y=2被**接收,以字典的形式保存下来,赋值给kwargs,即kwargs=
- 执行func( * args, ** kwargs),即func( * (1,),** {'y': 2, 'z': 3}),等同于func(1,z=3,y=2)
__EOF__

本文链接:https://www.cnblogs.com/amgulen/p/13943490.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构