文章目录
- 前言
- 一、函数的概念
- 二、函数的定义格式
- 三、函数的调用
- 四、函数的参数
-
- [1. 默认参数(缺省参数)](#1. 默认参数(缺省参数))
- [2. 变长参数](#2. 变长参数)
- 五、变量的作用域
-
- [1. 全局变量和局部变量](#1. 全局变量和局部变量)
- [2. 函数中操作全局变量](#2. 函数中操作全局变量)
- [3. `if`、`while`、`for`中的变量](#3.
if、while、for中的变量)
- 总结
前言
本文用于介绍Python中函数相关的概念,主要包括:函数的定义、函数的调用、函数的参数以及局部变量和全局变量等内容。
一、函数的概念
编程中的函数是一段可以被重复使用的代码片段,使用函数可以有效减少冗余代码,例如:
python
# 1. 求1~100的和
sum = 0
for i in range(101):
sum += i
print(f'1~100的和为{sum}') # 5050
# 2. 求100~300的和
sum = 0
for i in range(100, 301):
sum += i
print(f'100~300的和为{sum}') # 40200
# 3. 求1~1000的和
sum = 0
for i in range(1001):
sum += i
print(f'1~1000的和为{sum}') # 500500
这三段代码的处理逻辑是类似的,因此可以将重复的代码逻辑提取出来封装成一个函数,求和时直接调用该函数即可,例如:
python
def Sum(begin, end):
sum = 0
for i in range(begin, end + 1):
sum += i
return sum
# 1. 求1~100的和
print(f'1~100的和为{Sum(1, 100)}') # 5050
# 2. 求100~300的和
print(f'100~300的和为{Sum(100, 300)}') # 40200
# 3. 求1~1000的和
print(f'1~1000的和为{Sum(1, 1000)}') # 500500
二、函数的定义格式
定义格式
python
def 函数名(形参列表):
函数体
return语句
注意:
- 一个函数可以没有形参,也可以有多个形参;
- 一个函数可以有一个或多个
return语句,执行到return语句时函数会立即执行结束回到调用位置; - 由于Python是动态类型语言,函数的形参和返回值都不用声明类型,因此一个函数可以支持多种不同类型的参数调用。
返回值
Python中的一个函数可以有一个或多个返回值,当有多个返回值需要返回时,要使用,将它们分隔开,例如:
python
def getSumAndDef(num1, num2):
return num1 + num2, num1 - num2
a = 10
b = 20
Sum, Def = getSumAndDef(a, b)
print(f'{a} + {b} = {Sum}, {a} - {b} = {Def}') # 10 + 20 = 30, 10 - 20 = -10
Python中函数能返回多个值,本质是Python支持多元赋值。
如果函数调用者只想关注该函数的部分返回值,可以使用_忽略不关注的返回值,例如:
python
def getSumAndDef(num1, num2):
return num1 + num2, num1 - num2
a = 10
b = 20
_, Def = getSumAndDef(a, b)
print(f'{a} - {b} = {Def}') # 10 - 20 = -10
三、函数的调用
1. 函数的调用格式
1.1 格式
python
返回值 = 函数名(实参列表)
注意 :
函数必须先定义再使用,函数定义后不会执行函数体内容,只有当函数被调用时才会执行。
1.2 传参方式
调用函数时,可以根据函数的形参列表,将实参列表中的数据按顺序依次传给对应的形参,例如:
python
def func(x, y):
print(x)
print(y)
a = 10
b = 20
func(10, 20) # 10 20
也可以通过关键字参数来调整传参的顺序,显示指定当前实参传给哪个形参,例如:
python
def func(x, y):
print(x)
print(y)
a = 10
b = 20
func(y = 10, x = 20) # 20 10
2. 函数的调用方式
2.1. 链式调用
链式调用是指:把一个函数的返回值作为调用另一函数时的参数进行传入
python
def Sum(x, y):
return x + y
a = 10
b = 20
print(Sum(a, b)) # 30
将Sum函数的返回值作为print函数的参数进行传入
2.2. 嵌套调用
嵌套调用是指:在一个函数的函数体内部调用另一个函数
python
def Sum(x, y):
print(x) # 10
print(y) # 20
return x + y
a = 10
b = 20
print(Sum(a, b)) # 30
在Sum函数中调用print函数
2.3. 递归调用
递归调用是一种特殊的嵌套调用,它指的是一个函数在函数体内部嵌套调用自己
python
# 求一个数的阶乘
def factor(num):
if num == 1:
return num
else:
return num * factor(num - 1)
print(f'5的阶乘是{factor(5)}') # 120
在factor函数内部嵌套调用了factor函数,这就是递归调用(一层一层进行递归调用,当满足递归结束条件时再逐层返回)
2.3.1 递归的两个条件
- 存在递归结束条件
- 每进行一次递归,都会逐渐逼近结束条件
如果不能满足这两个条件,就会出现无限递归的情况,最终导致栈溢出(Stack Overflow)。
函数调用时,需要在函数调用栈中借了每一层函数调用的信息,但是函数调用栈的空间是有限的,如果函数调用层次太多,就会超出栈的最大范围,导致栈溢出。
2.3.2 递归的优缺点
优点
- 代码简洁:递归代码量通常比较少,对于天生具有递归结构的问题(树、图、分治、回溯、动态规划等),递归代码能直接映射问题定义,清晰反应自顶向下的分解过程。代码量通常远少于等价的循环+显示栈管理代码。
- 思维直观,符合数学归纳法:明确基础条件和递推公式就可以解决问题。在解决数列、组合数学等问题时很方便
- 简化复杂问题:将大问题分解为结构相同的小问题,是分支策略和回溯算法的基石,极大的降低了思考的复杂度
缺点
- 调试和理解难度较大:递归的"层层深入再层层返回"的过程不直观,导致代码往往难以理解,很容易超出掌控范围
- 栈溢出风险 :递归深度受限于调用栈大小,当递归过深时,会抛出
Stack Overflow - 性能开销大:每次递归调用都涉及栈帧的创建(保存参数、局部变量。返回地址等),与纯循环相比较,时间和空间开销都更大。递归代码可以转换为等价的循环代码,并且通常情况下循环版本的代码执行效率会更高,因为函数调用也有开销。
四、函数的参数
1. 默认参数(缺省参数)
类似C++编程语言,Python也支持给函数的形参指定默认值,在调用函数时,可以不给缺省参数传参(它会使用默认值),例如:
python
def factor(num = 3):
if num == 1:
return num
else:
return num * factor(num - 1)
print(f'5的阶乘是{factor(5)}') # 120
print(f'3的阶乘是{factor()}') # 6
可以看到,如果给函数传入实参,则函数会使用该实参,如果不给函数传入实参,则函数会直接使用默认值。
注意 :
在定义函数时,缺省参数需要放到普通参数的后面。
2. 变长参数
如果想让函数能接收任意个数的参数,可以在函数定义的形参名称前面添加*,这时函数将接收一个参数元组,可以通过形参名[下标]的方式访问传入的各个实参,例如:
python
def Func(*arg):
n = len(arg)
for i in range(n):
print(arg[i])
Func(1, 2, 4) # 1 2 4
Func(3, 4) # 3 4
五、变量的作用域
1. 全局变量和局部变量
每个变量都有自己的作用域:
- 定义在函数外部的变量,其作用域是全局,称为"全局变量";
- 定义在函数内部的变量,其作用域是函数体内,称为"局部变量"
注意:
- 局部变量只能在自己所在的函数体内生效;
- 不同作用域内允许存在同名变量
2. 函数中操作全局变量
函数体内使用的变量会优先在局部域中查找,如果局部域中找不到,会去全局域中查找,例如:
python
def Func():
print(x)
x = 10
Func() # 10
如果在函数体内想要修改全局变量,需要使用global关键字,声明该变量是全局变量。否则Python编译器会认为该变量是在函数体内创建的同名局部变量,导致函数体内对该变量的修改无法同步到函数体外,例如:
python
# 不使用global声明
def Func():
x = 20
print(x) # 20
x = 10
Func() # 20
print(x) # 10
# 使用global声明
def Func():
global x
x = 20
print(x) # 20
x = 10
Func() # 20
print(x) # 20
3. if、while、for中的变量
if、while、for等语句块不会影响变量的作用域,即在这些语句块中定义的变量,在语句块外部也能正常使用,例如:
python
for i in range(10):
print(i)
print(i) # 9
总结
以上就是今天要讲的内容,本文介绍了Python中函数的相关概念。本文作者目前也是正在学习Python相关的知识,如果文章中的内容有错误或者不严谨的部分,欢迎大家在评论区指出,也欢迎大家在评论区提问、交流。
最后,如果本篇文章对你有所启发的话,希望可以多多支持作者,谢谢大家!