函数基础
"""
函数的基础
1 什么是函数 -代码复用性 -可扩展性 -可维护性
具备功能性代码片段
2 函数的定义
格式:
def 函数名([参数列表]):
函数体
3 函数的调用
函数名([参数列表])
4 函数的分类
- 内置函数 python在运行后就把内置函数运行在内存中,list,len,str
- 自定义函数
- 第三方库函数 需要另外下载到本地的库,使用import导入,opencv人脸识别库
5 函数的返回值
- 无返回值: 函数调用后返回结果为None
- 有返回值: 使用return将结果返回
6 函数的参数
可以有0个,1个或多个
7 pass关键字
在函数定义时,暂时没有函数体,可以使用pass保证不报错
"""
案例1:如何定义一个函数
python
#1 定义函数
def zuocai():
print("准备食材")
print("洗菜")
print("炒菜")
print("装盘")
#调用函数
zuocai() #可以体现出函数的复用性,反复调用
zuocai()
zuocai()
#运行结果
准备食材
洗菜
炒菜
装盘
准备食材
洗菜
炒菜
装盘
准备食材
洗菜
炒菜
装盘
案例2:return关键字
python
#2 retun关键字
#计算两个数的和
def sum(x,y): #可以给函数定义参数,调用函数的时候输入参数
return x + y
res = sum(3,5) #调用函数把值赋给res
print(res) #结合print来输出结果
#运行结果
8
案例3:pass关键字
python
ef guanmen():
pass #作用:在函数定义时,暂时没有函数体,可以使用pass保证不报错
函数返回值
"""
1 函数的基础
2 函数的三个重要属性
- 函数的类型
function
- 函数的id
16进制的整数值
- 函数的值
封装在函数中的数据和代码
引用传递和值传递
3 函数的返回值
- 函数返回值的内容
- 多函数返回值问题
- return的另外一个意义
- retun不指定返回值返回None 与 不填return效果一致
- 可以提前结束函数类似break
"""
回顾一下函数基础
python
#1 回顾函数基础
def sum(x,y):
return x + y
#调用函数
res = sum(10,20)
print(res)
#查看函数的类型
print(type(sum)) #<class 'function'>
#函数也是一块内存空间,通过函数名可以看到函数的本质
print(sum) #打印一个16进制数的堆内存地址
print(id(sum)) #二进制的堆内存地址
#函数的引用传递
sum_test = sum #引用传递引用的是函数的地址
res = sum_test(10,20) #值传递,返回一个x+y的值给res
print(res)
以下为函数返回值的示例
python
def test_return():
print("test_return.....")
res = test_return()
print(res) #没有返回值返回None
#运行结果
None
#因为没有return或者return 不指定值都会返回None
return可以返回多种数据类型
python
def test_return1():
#return "zhangsan" #返回字符串
#return 10 #返回整数
#return [10,20,30] #返回列表
#return {"username":"zhangshan","age":18} #返回字典
#return range(100) #返回对象
return test_return1
res = test_return1()
print(res)
多个返回值
python
def test_return2():
return 10,20,"zhangsan"
res = test_return2() #一个变量接受返回的是个元组多个不同的数据类型
print(res)
#运行结果
(10, 20, 'zhangsan')
还可以多个变量接受一一对应
python
def test_return2():
return 10,20,"zhangsan"
res = test_return2()
print(res)
res1,res2,res3 = test_return2() #多个变量接受一一对应
print(res1)
print(res2)
print(res3)
#运行结果
10
20
30
return的另外一个意义除了返回函数执行结果
python
# 1.返回函数执行的结果
# 2.立即结束函数,返回被调处
def test_return3():
for i in [10,20,30]:
print(i)
return #retun可以提前结束函数
print("我在return后去执行")
print(test_return3())
#运行结果
None #因为使用return体检结束了函数
函数的参数
"""
函数的参数
1 形参和实参
形式参数: 定义函数时, 参数为形式参数
实体参数: 调用函数时, 形参变实参的过程,具备内存空间
扩展: 引用传递和值传递
- 引用传递: 函数本身传递过程,函数本身内存空间的指向
- 值传递: 函数在调用时,实际的数值和参数的传递过程
2 位置参数
具备传递的先后顺序
3 缺省参数
特性:
定义函数时,通过变量=默认值,定义形式参数
调用时, 可以省略, 以默认值传递参数
调用时, 如果给默认值改变参数值时, 会使用新传入的值
4 可变参数
特性: * 创建可变参数,一般写为 *args
可以传递0个, 一个或者多个
传入参数会自动打包为一个元组
5 命名关键字参数
特性: 写在 * 之后,用于在可变参数后添加指定参数
6 关键字参数
特性:
- 通过 ** 创建关键字参数, 一般写为kewards
- 可以传0个,1个或者多个
- 传递值时以k = v形式
- 会将参数打包为字典
7 参数的定义顺序
顺序: 必选参数>默认参数>可变参数>命名关键字参数>关键字参数
8 打包和解包
打包:
将多个参数,打包成元组或者字典
默认值参数传值后又可变参数,这主意默认值的传值问题
解包:
把元组或者字典解包传入可变参数与关键字参数中
"""
1 形式参数和实体参数
python
#1 形式参数和实体参数
#定义
def sum(x,y): #定义函数的时候的参数为形式参数
return x+y
#调用
print(sum(10,20)) #调用函数时传入的形式参数为实体参数
#运行结果
30
2 位置参数
python
"""
特性:
1 具备传递的先后顺序
"""
def test_arg1(x,y):
print(x/y)
test_arg1(10,2)
test_arg1(2,10)
#运行结果
5.0
0.2
3 缺省函数
python
def test_arg2(x,y="北京"):
print(f"寄快递: 商家的地址: {x},自己的地址: {y}")
test_arg2("广东")
test_arg2("广东","西安")
#运行结果
寄快递: 商家的地址: 广东,自己的地址: 北京
寄快递: 商家的地址: 广东,自己的地址: 西安
4 可变参数
python
def test_arg3(*arg):
print(arg)
test_arg3("不吃葱","加米饭","中辣")
#运行结果
('不吃葱', '加米饭', '中辣') #返回的是一个元组
5 命名关键字参数
python
#5 命名关键字参数
def test_arg4(a,*args,b,c):
print(a,args,b,c)
#test_arg4(22,"不吃葱","不吃蒜","来个烤肠","来杯饮料") #不指定命名关键字参数会报错
est_arg4(22,"不吃葱","不吃蒜",b = "来个烤肠",c = "来杯饮料") #命令关键字参数
#运行结果
22 ('不吃葱', '不吃蒜') 来个烤肠 来杯饮料
不指定命名关键字参数会出现以下报错

6 关键词参数
python
def test_arg5(**kewards):
print(kewards)
test_arg5(arg1 = "带杯饮料",arg2 = "带卫生纸",arg3 = "不要案例",arg4 = "加饭")
#运行结果
{'arg1': '带杯饮料', 'arg2': '带卫生纸', 'arg3': '不要案例', 'arg4': '加饭'}
#扩展如果不确定参数时,可以采用什么方式传入任意的值
#万能参数定义
def test_arg6(*args,**kewards):
print(args,kewards)
test_arg6("中辣","加饭",arg1 = "来杯饮料",arg2 = "XXX")
#运行结果
('中辣', '加饭') {'arg1': '来杯饮料', 'arg2': 'XXX'}
7 参数定义顺序
python
def test_arg7(a,b,c=2,*args,d,f,**kewards): #顺序: 必选参数>默认参数>可变参数>命名关键字参数>关键字参数
print(a,b,c,args,d,f,kewards)
test_arg7(1,2,3,4,44,d=5,f=6,arg1=7)
8 打包
python
def test_arg8(a,b=10,*args,d,**kewards):
print(f"a={a},b={b},args={args},d={d},kwward={kewards}")
test_arg8(10,d = "lisi")
test_arg8(10,20,d = "lisi")
test_arg8(10,20,100,200,300,d = "lisi")
test_arg8(10,20,100,200,300,d = "lisi",e="zhangsan",f="wangwu")
#运行结果
a=10,b=10,args=(),d=lisi,kwward={}
a=10,b=20,args=(),d=lisi,kwward={}
a=10,b=20,args=(100, 200, 300),d=lisi,kwward={}
a=10,b=20,args=(100, 200, 300),d=lisi,kwward={'e': 'zhangsan', 'f': 'wangwu'}
9 解包
python
c = (20,30,40)
e = {"username":"zhangsan","age":20}
test_arg8(10,20,*c,d='xsx',**e)
#运行结果
a=10,b=20,args=(20, 30, 40),d=xsx,kwward={'username': 'zhangsan', 'age': 20}
局部变量与全局变量
"""
1 函数的运行原理
在函数调用的时候会在栈中开辟一块内存空间
函数的调用过程就是压栈,函数执行完毕就会弹栈
2 全局变量和局部变量的问题
局部变量: 写在函数内部的变量或者参数
全局变量: 整个py文件
生命周期:
局部变量: 随着栈帧的创建而创建,随栈帧销毁而销毁
3 变量作用域问题
4 改变变量作用域
"""

1 测试全局变量与局部变量
python
#1 测试全局变量和局部变量
#测试全局变量和局部变量同名问题
#就近原则
name = 'zhangsan' #全局变量
def test():
name = 'lisi' #局部变量 #如果函数内内有定义,则会引用函数外的'zhangsan'
print(name)
print(test())
#运行结果
lisi
None
zhangsan
def test2():
global username #使用global可以使局部变量改为全局变量
username = 'wangwu'
return username
print(test2())
print(username)
#运行结果
zhangsan
wangwu
#如果没有把局部变量转换为全局,在函数外引用函数内的函数会报错
def test2():
#global username #使用global可以使局部变量改为全局变量
username = 'wangwu'
return username
print(username)

匿名函数与偏函数
"""
1 匿名函数 --简化代码
python没有这个概念,但是可以使用lambda关键字来简化函数的代码写法
2 lambda表达式
3 偏函数
"""
1 测试lambda表达式
python
#1 测试lambda表达式
#未使用匿名函数的函数构建
def sum(x,y):
return x + y
#使用lambda,两者效果一样
#多个参数
sum = lambda x,y: print(x+y)
#print(sum(10,20))
sum(10,20)
#一个参数
test = lambda x : print(x)
test(10)
#无参
test1 = lambda : print("hello")
test1()
lambda案例
python
#案例
test_list = [10,20,30,40,50,60]
print("排序前: ",test_list)
test_list.sort() #排序
print("排序后: ",test_list)
test_list_lambda = ["zhangsan","cakde","lisi","wangwu","sasa","yyy"]
print("排序前: ",test_list_lambda)
#test_list_lambda.sort() #按照首字母来进行排序
#排序规则的定义
test_list_lambda.sort(key = lambda x : len(x)) #更改sort的排序规则,构建一个匿名函数使用长度来排序
print("排序后: ",test_list_lambda)
#运行结果
排序前: [10, 20, 30, 40, 50, 60]
排序后: [10, 20, 30, 40, 50, 60]
排序前: ['zhangsan', 'cakde', 'lisi', 'wangwu', 'sasa', 'yyy'] #sort默认排序规则是字母开头
排序后: ['yyy', 'lisi', 'sasa', 'cakde', 'wangwu', 'zhangsan'] #通过元素长度来排序
2 偏函数
python
import functools
def test(x,y):
print(f"收件地址: {x},寄件地址: {y}")
test = functools.partial(test,y = "珠江学院") #偏函数
test("浙江")
#运行结果
收件地址: 浙江,寄件地址: 珠江学院
补充:
如果原函数本身给参数设置了默认值(如 def test(x, y="珠江学院")),看似也能实现 "固定参数",但它与偏函数的区别在于:
- 默认参数是原函数定义时固定的,所有调用者都会共享这个默认值,无法灵活创建多个不同预设值的版本。
- 偏函数是在原函数之外动态创建的,可以基于同一个原函数创建多个偏函数,每个偏函数预设不同的参数值。
本文章为学习后的产出笔记与实验记录,谢谢阅读,如有问题及时提出~