闭包
内部函数对 外部函数 作用域 里 变量 的引用
上面那句话,就是闭包的一个比较官方的解释,不太好理解,下面让我们来结合代码,解释一下
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
"""
解释和上面基本一致,函数的传递也是差不多的。