python基础——闭包、装饰器

闭包

定义:一个函数中再定义一个函数,其中里边的函数用到了外边函数的变量,则称这两个函数为一个闭包。
看一个闭包的例子:

def f1(x):
	def f2():
		return x+1
	return f2

ret = f1(10)
print(ret())

输出:
11

上述代码中,调用f1函数返回的f2函数的引用,即ret指向的是f2的引用,在调用ret时即是调用f2函数。
由于闭包引用了外部函数的局部变量,因此外部函数的局部变量不能及时释放,消耗内存。

装饰器

在不修改原来代码的前提下增加逻辑即可以用到装饰器。
先来看一下装饰器的功能:
1.引⼊⽇志
2.函数执⾏时间统计
3.执⾏函数前预备处理
4.执⾏函数后清理功能
5.权限校验等场景
6.缓存

举个例子:

无参数装饰器:
def func1(func):
	def func2():
		print("add test logic")
		return func()
	return func2

@func1
def work_platform():
	print("this is work_platform")

work_platform()

输出:
add test logic
this is work_platform
解释一下执行原理:

首先,python解释器从上向下执行代码,func1函数加载到内存中,在执行@func1时python解释器中会执行以下逻辑,将@func1下边的函数名作为func1参数,然后调用func1函数,即func1(work_platform),执行func1函数返回func2的引用,并且将返回值再次赋值给@func1下的函数名,即此时的work_platform指向的时func2函数,这样在调用work_platform时实际上是调用的func2,如果还不明白的话就以代码注释的形式再叙述一遍

def func1(func):  # python解释器遇到函数不执行,加载到缓存中
	def func2():
		print("add test logic")
		return func()
	return func2

# 执行到@func1的时候会将work_platform函数名作为参数传给func1,调用func1,即func1(work_platform)
# 调用func1函数后返回func2的引用,并将其赋值给work_platform,这样work_platform这个函数就会重新指向另外的函数,这样就会形成以下的形式
# 新work_platform -> def func2():
#                     print("add test logic")
#                     work_platform()  这个work_platform是原来指向的函数
# 这样再次调用work_platform函数时,就会调用新的work_platform指向的函数,而不是原来定义的那个函数
@func1  
def work_platform():
	print("this is work_platform")

work_platform()  # 这个work_platform指的是新work_platform

这样一来既增加了验证逻辑,又执行了原来函数的代码
以上这种装饰器由于被装饰的函数没有参数,所以称为无参数装饰器

带参数装饰器:
def func1(func):
	def func2(a,b):
		print("add test logic")
		print("a:{}".format(a))
		print("b:{}".format(b))
		return func(a,b)
	return func2

@func1
def work_platform(a,b):
	print("this is work_platform")
	print(a+b)

work_platform(1,2)

输出:
add test logic
a:1
b:2
this is work_platform
3

由于work_platform 函数指向的是func2,所以所带的参数也相应的传给func2

通用装饰器:即不论被装饰的函数中存在几个参数,装饰器都可以接受而不报错,所以在func2中使用不定长参数即可。
def func1(func):
	def func2(*args, **kwargs):
		print("add test logic")
		return func(*args, **kwargs)
	return func2

@func1
def work_platform(a,b):
	print("this is work_platform")
	print(a+b)

work_platform(1,2)
给装饰器加参数,即是在装饰器的外边再加一层函数,即在原有装饰器的基础上设置外部变量
def xiaogu(auth):
	def func1(func):
		def func2(*args, **kwargs):
			if auth == "root":
				print("auth is big")
			elif auth == "user":
				print("auth is small")
			print("add test logic")
			return func(*args, **kwargs)
		return func2
	return func1

@xiaogu("root")
def work_platform(a,b):
	print("this is work_platform")
	print(a+b)

work_platform(1,2)
一个函数有多个装饰器的情况:装饰器会自上而下依次执行
def func1(func):
    def func2(*args, **kwargs):
        print("add test logic")
        return func(*args, **kwargs)

    return func2

def demo(func):
    def func3(*args, **kwargs):
        print("demo func3")
        return func(*args, **kwargs)
    return func3

@func1
@demo
def work_platform(a, b):  # 先执行func1装饰器,再执行demo装饰器,最后执行work_platform函数
    print("this is work_platform")
    print(a + b)

输出:
add test logic
demo func3
this is work_platform
3
发布了36 篇原创文章 · 获赞 2 · 访问量 932

猜你喜欢

转载自blog.csdn.net/zzrs_xssh/article/details/104524114
今日推荐