函数的基本介绍
【一】函数的特点以及使用情形
【1】函数的特点:
- 封装(Encapsulation):
- 函数封装了一段特定的代码,将其作为一个独立的单元。这有助于提高代码的可维护性和可读性。
- 重用性(Reusability):
- 函数可以在程序中的不同位置被调用,实现了代码的重用。通过调用函数,可以避免重复编写相同的代码。
- 参数(Parameters):
- 函数可以接受输入参数,这样可以在函数内部使用外部提供的数据。参数使得函数更加通用,适用于不同的输入。
- 返回值(Return Value):
- 函数可以返回结果,这样调用者可以获取函数的输出。返回值是函数向外部提供结果的一种方式。
- 模块化(Modularity):
- 函数可以作为模块,通过函数的组合可以构建复杂的程序。模块化使得代码结构更清晰,易于理解和维护。
- 局部变量(Local Variables):
- 函数内部可以定义局部变量,这些变量的作用范围仅限于函数内部。这有助于避免命名冲突和提高代码的安全性。
【2】使用情形:
- 代码复用:
- 当某段代码需要在程序的不同部分被重复使用时,将其封装成函数,可以通过函数调用来实现代码的复用。
- 抽象操作:
- 函数提供了对某个操作的抽象,使得调用者无需关心操作的具体实现细节。这样可以提高代码的抽象层次,简化调用者的逻辑。
- 模块化设计:
- 大型程序通常由许多小模块组成,每个模块可以是一个函数。通过模块化设计,可以更容易地理解和维护代码。
- 参数化操作:
- 函数可以接受参数,使得操作变得更加通用。通过参数传递不同的值,可以在不同的上下文中使用同一个函数。
- 组织结构:
- 函数有助于组织程序的结构。将不同功能的代码封装在不同的函数中,使得程序更加有序,易于理解。
- 提高可读性:
- 使用函数可以将复杂的逻辑分解成简单的步骤,提高了代码的可读性。每个函数都承担特定的责任,使得代码更具清晰度。
- 测试和调试:
- 函数可以更容易地进行单元测试,因为函数是独立的单元。在调试时,函数也提供了更容易定位问题的标志点。
【二】函数的定义与调用
【1】定义的语法
(引)基本概念
| def 函数名(参数1,参数2,...): |
| """文档描述""" |
| 函数体 |
| return 值 |
- def: 定义函数的关键字;
- 函数名:函数名指向函数内存地址,是对函数体代码的引用。函数的命名应该反映出函数的功能;
- 括号:括号内定义参数,参数是可有可无的,且无需指定参数的类型;
- 冒号:括号后要加冒号,然后在下一行开始缩进编写函数体的代码;
- """文档描述""": 描述函数功能,参数介绍等信息的文档,非必要,但是建议加上,从而增强函数的可读性;
- 函数体:由语句和表达式组成;
- return 值:定义函数的返回值,return是可有可无的。
(1)空函数
(2)无参无返回值
| def 函数名(): |
| 函数体 |
| '''例如''' |
| def add(): |
| print(1+1) |
(3)有参无返回值
| def 函数名(参数1,参数2,...): |
| 函数体 |
| '''例如''' |
| def add(x,y): |
| print(x+y) |
(4)有参有返回值
| def 函数名(参数1,参数2,...): |
| 函数体 |
| return 数据 |
| '''例如''' |
| def add(x,y): |
| msg=x+y |
| return msg |
【2】函数的调用方式
(1)直接调用
| def add(x,y): |
| return x+y |
| print(add(1,2)) |
(2)表达式调用
| def add(x,y): |
| return x+y |
| result = add |
| print(result(1,2)) |
| |
(3)函数作为参数
| def add(): |
| return 1+9 |
| def mix(x,y): |
| return x*y |
| print(mix(x=add(),y=10)) |
【三】函数的参数
【1】函数的参数类型[形参&实参]
(1)形参(形式参数)
(2)实参(实际参数)
| def add(形参1,形参2): |
| return 实参1+实参2 |
| add(形参1=实参1,形参2=实参2) |
(3)参数类型弱警告
- 可以为形参设定期望参数
- 通过
函数名(参数1:数据类型,参数2)
实现
- 弱警告并不会报错,只是警示开发人员,此处希望得到的数据类型是什么
| |
| def add(x: int, y): |
| return x + y |
| |
| |
| add('a', 2) |

【2】传参数
(1)位置传参
- 在调用函数时,按照从左到右的顺序依次定义实参,称为位置实参
- 顺序错误将导致传递数值错误
- 按位置传参数据
数量
必须一致,否则将导致报错
| def add(a,b,c): |
| return a+b+c |
| |
| print(add('我','爱','你')) |
| |
| print(add('爱','我' '你')) |
| |
| print(add('我', '爱', '你','吗?')) |
| |
(2)关键字传参
| def add(a, b, c): |
| return a + b + c |
| |
| print(add(a='我', b='爱', c='你')) |
| print(add(b='爱', a='我', c='你')) |
| |
(3)位置参数和关键字参数混合使用
- 需要注意,关键字参数不可以在位置参数前,否则将报错
| def add(a, b, c): |
| return a + b + c |
| |
| print(add('I', b='love', c='you')) |
| |
| print(add(a='I', 'love', c='you')) |
| |
| |
(4)默认参数
- 在定义函数时,就已经为形参赋值,这类形参称之为默认参数
- 当函数有多个参数时,需要将值经常改变的参数定义成位置参数,而将值改变较少的参数定义成默认参数。
| |
| def add(a,c,b='love'): |
| return a+b+c |
| |
| print(add('我','你')) |
| |
| |
| print(add('我','你','爱')) |
| |
| |
| |
| |
| def add(a, *, b='love', c): |
| return a + b + c |
| print(add('I', b='love', c='you')) |
【3】可变长参数
(1)可变长位置参数*args
- 如果在最后一个形参名前加
*
号,那么在调用函数时,溢出的位置实参,都会被 *
接收,以元组的形式保存下来赋值给该形参
- 既然时元组就可以进行解包赋值的操作
| |
| def foo(x, y, z=1, *args): |
| print(x) |
| print(y) |
| print(z) |
| print(args) |
| |
| |
| foo(1, 2, 3, 4, 5, 6, 7) |
| |
| |
| |
| |
| |
| def add(*args): |
| res = 0 |
| for i in args: |
| res += i |
| return res |
| |
| |
| res = add(1, 2, 3, 4, 5) |
| print(res) |
| |
| |
| |
| def foo(x, y, *args): |
| print(x) |
| print(y) |
| print(args) |
| |
| |
| L = [3, 4, 5] |
| foo(1, 2, *L) |
| |
| |
(2)可变长关键字参数**kwargs
- 如果在最后一个形参名前加
**
号,那么在调用函数时,溢出的关键字参数,都会被 **
接收,以字典的形式保存下来赋值给该形参
| def foo(x, **kwargs): |
| print(x) |
| print(kwargs) |
| |
| |
| foo(y=2, x=1, z=3) |
| |
| |
| |
| |
| def foo(x, y, **kwargs): |
| print(x) |
| print(y) |
| print(kwargs) |
| |
| |
| dic = {'a': 1, 'b': 2} |
| foo(1, 2, **dic) |
| |
| |
| |
| |
| |
| |
【4】命名关键字参数*
-
想要限定函数的调用者必须以key=value的形式传值
-
需要在定义形参时,用 *
作为一个分隔符号,*
号之后的形参称为命名关键字参数。
-
对于这类参数,在函数调用时,必须按照key=value的形式为其传值,且必须被传值
| def register(name, age, *, sex, height): |
| pass |
| |
| |
| |
| register('user', 18, sex='male', height='1.9m') |
| |
| |
| register('user', 18, 'male', '1.9m') |
| |
| |
| register('user', 18, height='1.9m') |
【5】混合使用
- 综上所述所有参数可任意组合使用,但定义顺序必须是:
位置参数
、默认参数
、*args
、命名关键字参数
、**kwargs
- 可变参数
*args
与关键字参数**kwargs
通常是组合在一起使用的
- 如果一个函数的形参为
**args
与**kwargs
,那么代表该函数可以接收任何形式、任意长度的参数
| def wrapper(*args,**kwargs): |
| pass |
- 在该函数内部还可以把接收到的参数传给另外一个函数(这在装饰器的实现中大有用处)
| def func(x, y, z): |
| print(x, y, z) |
| |
| |
| def wrapper(*args, **kwargs): |
| func(*args, **kwargs) |
| |
| |
| wrapper(1, z=3, y=2) |
| |
- 提示:
*args
、**kwargs
中的args和kwargs被替换成其他名字并无语法错误,但使用args、kwargs是约定俗成的。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了