函数
- 函数是一个具有特定功能的代码块。
- 函数把代码进行封装,提高代码的重用性,提高开发效率,降低后期维护成本。
- 函数可以分为两类:
- 执行过程函数:函数体内完成一定的功能即可,没有返回值
- 具有返回值的函数:函数体内完成一定的功能,并且返回一个结果到函数调用处
def 函数名(参数列表):
函数功能代码...
函数的参数
调用带参数的函数实质上是对变量的赋值操作
def write(title):
print(f'今天的《{title}》决定咕咕掉!')
write('三脚猫侦探')
#(输出) 今天的《三脚猫侦探》决定咕咕掉!
普通参数
- 又称 位置参数,顺序参数
- 是调用时必须传递的参数
def func(a,b):
print(a+b)
func(1,2)
#(输出) 3
默认参数
- 在定义函数时指定了默认值的参数
- 调用时如果不给这些参数,那么将使用默认值
def area(r,x=3) # 求圆面积,默认π值为3
print(x*r*r)
# 求半径为2的圆面积
area(2,3.14) # 给π值3.14
#(输出) 12.56
area(2) # 不给π值,使用默认值
#(输出) 12
收集参数
- 定义一个形参,收集多余的参数并以 元组 的形式存储起来
- 定义收集参数只需在形参名前加 * 号即可
def func(x,*args): # args即为收集参数
result = 100 # 初始值为100
if x == '+': # 如果第一个参数是加号
for i in args: # 从元组args中一个个取出与初始值相加求和
result += i
else:
for i in args: # 如果第一个参数是减号
result -= i # 从元组args中一个个取出与初始值相减求差
print(result)
func('+',30,10,20)
#(输出) 160
func('-',30,10,20)
#(输出) 40
命令关键字参数
- 为了在 收集参数 后面的形参可以接受参数
- 关键字参数定义在 收集参数 的后面,通过形参的名字指定传递
# 栗子与刚才收集参数的举例相同
def func(x,*args,y):
result = 100
if x == '+':
for i in args:
result += i
else:
for i in args:
result -= i
print(result>y) # 打印 运算结果是否比y大
func('+',30,10,20,y=150) # 注意最后y=150是通过形参的名字来传递的
#(输出) True
# tip:普通参数也可以按照形参名字来传递
func(x='-',30,10,20,y=150) # x='-'是普通参数
#(输出) False
关键字参数收集
- 把多余的关键字参数以 字典 形式收集存储
- 定义的参数前加 ** 号即可
# 还是老例子
def func(x,*args,y,**kwargs): # kwargs即关键字收集参数
result = 100
if x == '+':
for i in args:
result += i
else:
for i in args:
result -= i
for k,v in kwargs.items(): # 使用for循环打印字典内容
print(k,'=',v,end=' ')
print(result>y)
func('+',30,10,20,y=150,time='2020.6.1',event='测试',people='劳模琴酒')
#(输出) time = 2020.6.1 event = 测试 people = 劳模琴酒 True
参数的摆放问题
- 注意形参声明的位置,传参数时需要对排入座,一类参数一排,排好一排再去坐下一排,不要乱坐
- 可参考传参顺序:普通参数,默认参数,收集参数,关键字参数,关键字收集参数
函数返回值return
- 使用return返回内容或数据到函数调用处
- 如果在函数中没有使用return,或者return后面没有任何内容,默认返回None
变量作用域
局部变量
- 在函数内部使用的变量
- 可以获取定义在函数外的局部变量
- 函数内定义的局部变量,在函数为不能直接使用
- 可变数据类型的局部变量在函数内部能直接更改
- 不可变数据类型(数字、元组、字符串)的局部变量在函数内不能直接更改
num = 10
varlist = [1,2,3]
def func():
name = '琴酒'
print(num) # 可以获取定义在函数外的局部变量
varlist[2] = 5 # 能直接更改
# num += 1 # 不能直接修改
func()
#(输出) 10
print(varlist)
#(输出) [1,2,5]
# print(name) # 无法获取name
全局变量
在函数内通过 global 声明某个在函数体外定义好的局部变量,那么该变量将不分函数内外使用
age = '柯南' # 就像共享单车
def func():
age = '新一' # 对自家自行车刷漆不影响共享单车
func()
print(age)
#(输出) 柯南
# 使用 global 声明
age = '柯南' # 共享单车
def func():
global age # 将共享单车搬回家
age = '新一' # 对共享单车刷漆
func()
print(age)
#(输出) 新一
内函数
变量和函数都有作用域,内函数即定义在函数内的函数
def outer():
age = '新一'
def inner()
print(age)
inner()
outer()
#(输出) 新一
nonlocal关键字
- 与global类似,nonlocal可以在内函数中使用上一层函数中的变量
def outer():
age = '新一'
def inner():
nonlocal age # age本来只能访问,但不能修改
age = '柯南' # 声明后变为可以修改
inner()
print(age)
outer()
#(输出) 柯南
递归函数
- 自己调用自己的函数
- 递归函数内必须要有结束,不然就会一直调用下去,直到栈溢出
- 即在递归函数中需要判断 什么时候要做递归调用 什么时候结束递归调用
# 递归过程可以通过模拟来回报数加深理解
def digui(num):
print(num) # 当前同学报数
if num < 4: # 4个人参与报数
digui(num+1) # 下个要报的数(num+1)
print(num) # 报完一遍后,往回报数,你需要再报一遍自己的数字
digui(1) # 从1开始报数
#(输出) 1 2 3 4 4 3 2 1
'''
解析当前递归的执行过程
digui(1) ==> 1
digui(1+1) ==> 2
digui(2+1) ==> 3
digui(3+1) ==> 4 最后一名同学报完了,num<4不成立,开始往回报
digui(4) ==> 4 从最后一名同学再次报4,开始往回报数
digui(3) ==> 3
digui(2) ==> 2
digui(1) ==> 1
'''