闭包函数与装饰器

本文深入探讨了闭包函数的概念,强调了引用外部变量并在定义域外执行的特性。通过实例解析了如何判断一个函数是否为闭包,并介绍了装饰器作为闭包的应用,用于在不修改原有代码的基础上增加额外功能。文中还展示了装饰器在日志、性能测试等场景下的应用,并提供了多个装饰器实现示例。
摘要由CSDN通过智能技术生成

在这里插入图片描述

闭包函数

简单来说,一个函数定义中引用了函数定义外的变量,并且该函数可以在定义的环境外被执行,外层函数返回内层函数的函数地址(函数体),我们把这样的函数称为闭包函数
注意:如果返回的函数中没有引用父函数中定义的局部变量,那么返回的函数不是闭包函数。

# 定义一个函数
def func1():
	print("世界那么大,我想去看看")
	
print(func1)  # 返回函数地址
"""
返回结果  为func1的内存地址
<function func1 at 0x0000021F96CE77F0>
"""

# 定义一个简单的闭包函数
def func1():
	print("世界那么大,我想去看看")
	def func2():
		print("身上没钱,还是别去了吧")
	return func2
# 调用函数
f = func1() # f = func1 = func2
func1()()  # f = func1
print(func1) # 打印func1函数的内容 和 func2的内存地址

判断是否是闭包函数

函数 _ _closure _ _,当函数是闭包函数时,返回cell 元素,不是闭包函数时,返回None

  1. 返回cell时:
def name():
	print("python")
	def res():
		print("任你选择")
	print(res.__closure__) # (<cell at 0x000002A37ABE2AD0: str object at 0x000002A37A8834B0>,)
	return res
  1. 返回None:
name = "小红"
def name_1():
	print("python")
	def res():
		print("name")
	print(res.__closure__)  
	return res 
name_1() 
"""
返回结果:

python
None

"""

你以为这就完了吗 ?学习闭包就是为了后面的装饰器做准备的。
在这里插入图片描述

装饰器 (重点)

在这里插入图片描述
装饰器就是一个闭包,装饰器是闭包的一种应用,可以让其他函数或类在不需要做任何代码修改的前提下增加额外功能,装饰器的返回值也是一个函数/类对象。
应用场景:插入日志、性能测试、事务处理、缓存、权限校验等。

# 定义一个简单的装饰器
def inout(test):
	print("外层代码")
		def inter():
		print("此处为新添加的代码 1")
		test() # 旧代码的位置
		print("此处为新添加的代码 2")
	return inter # 返回内存函数的地址
	
# 定义一个需要被修改的旧代码
def old_def():
	a = 5
	b = 6
	c = a + b
	print("{}+{}={}".format(a,b,c))
	return old_def
	
# 修改旧代码
inout(old_def)()

"""
输出结果:

外层代码
此处为新添加的代码 1
5+6=11
此处为新添加的代码 2
"""

inout(old_def())  # 执行旧代码后再执行装饰器外层函数,未执行内层函数。
"""
输出结果:

5+6=11
外层代码
"""
注意:当取函数时未添加括号,输出为函数的内存地址

**@**符号,用一个简短的方式来生成一个被装饰的函数。

# 计算一个函数的运行所需要的时间
import datetime # 导入datetime模块

def count_time(test):
    def inter():
        start_time = datetime.datetime.now() # 程序开始时间
        print("开始时间为{}".format(start_time))
        test() # 程序
        end_time = datetime.datetime.now() # 程序结束时间
        print("结束时间为{}".format(end_time))
        sum_time = end_time - start_time # 结束—开始时间就是共运行时间
        print("执行该程序共计:%s" % sum_time)

    return inter

格式一: 递归
    
# 这里将内部函数递归嵌套在一个函数result中,
# 直接获取 1+2+3+...+10 结果,避免函数重复在装饰器中重复调用函数。
@count_time
def result():
    def num_sum(x):
        if x >= 5:
            return 0
        else:
            return x + num_sum(x+1)
    print("这里是个函数num_sum:{}的递归".format(num_sum(1)))

result() # 用 @count_time 方式调用装饰器,调用整个函数就相当方便。


格式二: 循环
n = 0 
@count_time
def num_sum():
    global n # 声明 使用全局变量
    for i in range(101):
        n += i  # n = n + 1
    return print("总数:{}".format(n))
    
num_sum()

基础的闭包与装饰器我们要掌握,在后面学习中中还会遇到,不然在学习的可能就会掉崩溃噢。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值