python 高级函数
python高级函数
一:闭包
1.1 什么是闭包
python 函数是支持嵌套的。如果在一个内部函数中对外函数作用域(非全局作用域)的变量进行引用,那么内部函数就会被称为闭包.
闭包需要满足 3 个条件
- 存在与两个嵌套关系的函数中,并且闭包是内部函数
- 内部函数引用了外部函数的变量
- 外部函数会返回内部函数的函数名
1.2 python函数带小括号和不带小括号的区别
1、不带括号时,调用的是这个函数本身 ,是整个函数体,是一个函数对象,不需等该函数执行完成
2、带括号(此时必须传入需要的参数),调用的是函数的return结果,需要等待函数执行完成的结果
如果函数本身带有参数的时候,带括号就就必须带参数,同理函数本身不带参数,带括号就不能带参数
1.3 演示内置函数
复制# 演示内置函数.内置函数是闭包的基础
def a(): #第一步,定义外部函数
b = 1 # 3,执行外部函数代码
def c(): # 4 定义内部函数
print(b) #执行内部函数代码
c() # 5 调用内部函数
a() # 2 调用外部函数
# 输出结果:
1
1.4 演示外部函数以接收返回值方式访问内部函数
复制# 演示把内部函数返回(闭包的必要条件),使得外部可以用接收返回值的方式,来访问内部函数
def a():
def b():
return 1 # 定义了内部函数的返回值为1
# 不带括号时,调用的是这个函数本身 ,是整个函数体,是一个函数对象,不需等该函数执行完成
return b # 直接返回函数名,
# 使用变量rst 接收了外部函数的返回值.rst就相当于b
rst = a()
print(rst) #rst就是内部函数b, 可以理解为print(b)(但是不能使用该语句)
print(rst()) # rst() 是调用内部函数,可以理解为print(b())(但是不能使用该语句)
print(a()()) # a()() 和rst()相同
# 输出:
<function a.<locals>.b at 0x000001F3B6C83160> #返回的是a.b
1
1
1.5演示一个函数作为另一个函数的参数
复制# 使用一个函数作为另一个函数参数的情况
# func_a ,接收到外部传入的参数,参数是函数名,表示是该函数本身而不是该函数执行结果
def a(func_a): # 可以传递任意函数
print("您好,我是a")
# 将传入的值,加上(),表示调用该函数体的执行结果.
func_a() # 可以对已定义的函数做额外的操作,而不需要修改原来的函数
print("goodby")
def b():
print("您好,我是b")
def c():
print("您好,我是c")
def d():
print("您好,我是d")
# 将函数体作为参数传递给 a 函数
a(b)
a(c)
a(d)
# 输出结果:
"""
您好,我是a
您好,我是b
goodby
您好,我是a
您好,我是c
goodby
您好,我是a
您好,我是d
goodby
"""
1.6演示闭包函数
复制# 演示闭包函数
def outer(start=0): # 1,定义外部函数.默认参数start=0
count = [start] # 3 执行外部函数代码.count = [5]
def inner(): # 4 定义内部函数
count[0] += 1 # 8 执行内部函数代码,count值==>6
return count[0] #9 返回值为count[0],即6
# 返回值为内部函数名,相当于返回该函数体.
return inner # 5 返回值
#2, 调用外部参数,传入值为5
out = outer(5) # 6, out 变量接收外部函数返回值.该返回值为内部函数体.
print(out()) # 7, 此时out(),相当于inner(),调用内部函数,获取返回值
# 10, print 打印内部函数的返回值,即print(6)
# 输出结果:
6
1.7 使用闭包实现案例
复制# 有银行卡才能执行汇款操作
# 外部函数为创建银行卡
# 内部函数为汇款的操作
def bank(is_vip, action):
if is_vip:
print("尊敬的客户您好,欢迎光临!")
else:
print("您好,给您新办了一张卡")
if action == "hui":
def remit():
print("进行汇款操作")
return remit
if action == "cun":
def cunkuan():
print("进行存款操作")
return cunkuan
card = bank(False,"cun")
card()
card = bank(True,"hui")
card()
# 输出结果:
您好,给您新办了一张卡
进行存款操作
尊敬的客户您好,欢迎光临!
进行汇款操作
二: 装饰器
2.1 什么是装饰器
假设我们已经定义了一个函数,后续可能会增加临时的需求,例如插入日志,我们可以增加一个包裹函数,由它来负责这些额外的需求,这个包括函数就是装饰器
装饰器主要用于以下场景:
- 引入日志
- 函数执行时间统计
- 执行函数前预备处理
- 执行函数后清理功能
- 权限校验
- 缓存
2.2 演示装饰器
装饰器是一个函数,它需要接收一个参数,该参数表示被修饰的函数.
复制# 演示装饰器
def a(fun_a): # 1,定义外部函数(装饰器)
print("装饰器开始工作!") # 4, 外部函数(装饰器)代码执行
def b(): # 5, 定义内部函数(闭包)
print("闭包开始工作") # 10, 执行内部函数的代码
fun_a() # 11,这是外部函数的参数,由于传递进入的是一个被装饰函数的函数名.加上小括号后,相当于调用该函数,获取该函数的执行结果decorator()
# 13 获取装饰函数的执行结果
print("装饰器工作结束") # 6, 外部函数代码执行
return b # 7 返回值. 返回值为内部函数名.表示是该函数体
def decorator_a(): # 2, 定义装饰函数
print("这是被装饰函数") # 12执行装饰函数内部代码
rst = a(decorator_a) # 3, 调用外部函数(装饰器)a,传入参数为函数名,使用变量rst 接收函数 a 的返回值
# 8, rst 接收a的返回值.由于返回值是内部函数b的函数体,此时,rst 就相当于内部函数b
rst() # 9, 执行rst(),就相当于b(),调用内部函数b(),获取该函数执行结果
# 14, 获取内部函数的执行结果
# 输出结果:
"""
装饰器开始工作!
装饰器工作结束
闭包开始工作
这是被装饰函数
"""
2.3 演示装饰器(2)
通过在函数定义的前面添加@符号和装饰器名,实现装饰器对函数的包装
复制from functools import wraps
def a(func_a):
print("装饰器开始工作")
@wraps(func_a) #可以防止注释使得函数名错乱
def b():
print("闭包开始工作")
func_a()
print("装饰器工作结束")
return b
@a # 等效于abc = a(abc)
def abc():
print("想要被装饰")
abc()
print("函数名是",abc.__name__)
# 输出结果:
"""
装饰器开始工作
装饰器工作结束
闭包开始工作
想要被装饰
函数名是 abc
"""
注意: 如果多个装饰器应用在一个函数上,调用顺序是从下至上
如:
复制@warp_one
@warp_two
def test():
print("---test---")
# 执行顺序:
先执行@warp_two
后执行@warp_one
2.4 演示装饰有参数的函数
复制def warp(func):
def inner(a, b):
print("开始验证权限")
func(a, b)
return inner
# @warp
def test(a, b):
print("a=%d, b=%d" % (a, b))
test = warp(test)
test(1, 2)
# 输出结果:
开始验证权限
a=1, b=2
2.5 带有返回值的装饰器
复制# 演示带有返回值的装饰器
def func(function_name):
def func_in():
return function_name()
return func_in
@func #等效于 test=func(test)
def test():
return "hello world"
print(test())
# 输出结果:
hello world
2.6 带有参数的装饰器
如果给装饰器添加参数,需要增加一层包装,先传递参数,然后再传递函数名.
复制def outer(args):
def func(a):
print("这是一个有返回值的闭包")
def func_in():
print(args)
return a()
return func_in
return func
func = outer("hello")
@func # 等效于test=func(test)
def test():
return "hello world"
print(test())
# 输出结果:
"""
这是一个有返回值的闭包
hello
hello world
"""
三:闭包,装饰器总结
一:闭包:
-
一个函数包含另一个函数
-
外部函数return了内部函数名
-
内部函数调用了外部函数的变量
----- 这个内部函数叫做闭包
特点:闭包不能直接别调用,而是需要调用外部函数获得返回值;
使用该返回值(),来调用内部函数
二:装饰器:
-
在外部函数的参数部分接收函数名
-
在内部函数的函数体中调用参数对应的函数
-
外部函数返回了内部函数名
-
调用外部函数传入函数名获取返回值(闭包)
-
通过闭包调用,实现对参数对应的函数调用
-
可以通过@装饰器名,来替代闭包传参的过程
特点:装饰器的调用相对安全可靠,并且不会改变原函数的逻辑
四: 常见的python内置函数
4.1 map函数
map 函数会根据提供的函数对指定的序列做映射
map 函数的定义如下:
- map(function,iterable...
- 参数function 表示函数的名称
- 参数iterable 可以是序列,支持迭代的容器或者迭代器
map 函数的作用就是以 iterable 中每个元组调用function函数,把每次调用后返回的结果保存为迭代器对象
复制# 演示map 函数
func = lambda x: x + 2
rst = map(func, (1, 2, 3, 4, 5))
print(list(rst))
# 输出结果
[3, 4, 5, 6, 7]
复制func = lambda x,y: x + y
rst = map(func, (1, 2, 3, 4, 5), [0, 7, 4, 6, 8])
print(list(rst))
# 输出结果:
[1, 9, 7, 10, 13]
map 函数的执行过程
4.2 filter 函数
filter 函数会对指定序列执行过滤操作
filter 函数定义如下:
- filter(function, iterable)
- function 参数可以是函数名成,或者None
- iterable参数可以是序列,支持迭代器的容器,或者迭代器
复制# 演示filter函数
func = lambda x: x % 2
# 注意,0代表False , 1 代表True.
rst = filter(func, [1, 2, 3, 4, 5, 6, 7, 8])
print(list(rst))
func = lambda x: x > 5
rst = filter(func, [1, 2, 3, 4, 5, 6, 7, 8])
print(list(rst))
# 输出结果:
[1, 3, 5, 7]
[6, 7, 8]
filter 函数的执行过程
4.3 reduce 函数
reduce 函数会对参数序列中的元素进行累积
.再python3,中,需要先 fucntools模块引入
reduce函数的定义如下:
- reduce(function,iterable[,initializer])
- function 是一个带有两个参数的函数.function 参数不能为None
- iterable 是一个迭代器对象
- initializer 表示固定的初始值
复制# 演示reduce 函数
from functools import reduce
func = lambda x,y: x + y
rst = reduce(func,[1,2,3,4,5,6,7,8,9,10])
print(rst)
# 输出结果:
55
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现