闭包、装饰器

闭包

内部函数外部函数 作用域变量引用
上面那句话,就是闭包的一个比较官方的解释,不太好理解,下面让我们来结合代码,解释一下

def output(): # 从 这里到 return 都是 外部函数 的 作用域
	a = 10 # 这里就是 外部函数作用域里面的变量
	print("这是外部函数")
	def inner(): # 内部函数
		print("这是内部函数")
		print(a+10)
	return inner
if __name__ == "__main__":
	a = output() # 这里是调用外部函数 -- 并将返回值 赋予 a
	a() # a -- 这里就表示内部函数 inner,a() -- 表示调用 内部函数inner
result:
这是外部函数
这里内部函数
20

装饰器

在不影响原有函数的功能的情况下,还可以添加新的功能
场景:拿到第三方API,但是第三方API不允许改动,可以使用装饰器自行添加功能。
装饰器也利用了闭包函数
举例:我们有一个函数 func1 ,函数里面会打印一句话,之间调用它,会打印出来这句话,但是我们想在不改动这个函数的前提下,在函数执行前,打印 before,函数执行之后,打印after,那我们怎么来做呢?

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

我们使用下面的操作,来进行

def output(origin):
	def inner():
		print("before")
		origin()
		print("after")
	return inner

func1 = output(func1)
func1()
# result:
"""
before
this is func1
after
"""

经过上面的操作,我们成功在 func1执行前后,打印了输出,下面我来解释一下,上面的内容

func1 = output(func1)
# 这行代码是,将上面我们定义的func1作为实参,传入到函数output里面,调用函数output
# 然后返回值,赋予 变量func1,这里的func1 其实就是 函数output里面的inner了
func1()
# 这行代码呢,其实就是调用inner函数,肯定就会执行inner函数体里面的内容了
# 先打印 before 在执行 origin函数,这里的origin函数就是我们传入的func1函数,然后再打印 after

这种看起来,是不是很复杂,Python内部给我们定义了一种语法糖可以简化操作,如下

# 完整代码
def output(origin):
	def inner():
		print("before")
		origin()
		print("after")
	return inner

@output # 其实等价于 func1 = output(func1)
def func1():
	print("this is func1")

func1()
# result:
"""
before
this is func1
after
"""

这里的结果和上面是一致的,是不是简便了很多了。

我们上面写的装饰器都是没有参数的,那我们怎么使用参数呢
# 完整代码
def output(origin):
	def inner(*args,**kwargs):
		print("before")
		origin(*args,**kwargs)
		print("after")
	return inner

@output # 其实等价于 func1 = output(func1)
def func1(a):
	print("this is func1",a)

func1(3)
# result:
"""
before
this is func1 3
after
"""

解释和上面基本一致,函数的传递也是差不多的。

上一篇:在这之后的两天又出现了w3wp进程找不到的情况了


下一篇:pimpl模式,编译防火墙