装饰器代码示例:
def wrapper_out1(func):
print('--out11--')
def inner1(*args, **kwargs):
print("--in11--")
ret = func(*args, **kwargs)
print("--in12--")
return ret
print("--out12--")
return inner1
def wrapper_out2(func):
print('--out21--')
def inner2(*args, **kwargs):
print("--in21--")
ret = func(*args, **kwargs)
print("--in22--")
return ret
print("--out22")
return inner2
@wrapper_out2 # 相当于 wrapper_out2 = wrapper_out2(test)
@wrapper_out1 # 相当于 wrapper_out1 = wrapper_out1(test)
def test():
print("--test--")
if __name__ == '__main__':
test()
#下面这些是代码output的结果
# --out11--
# --out12--
# --out21--
# --out22
# --in21--
# --in11--
# --test--
# --in12--
# --in22--
装饰器原理
import time
def showtime(func):
def wrapper():
start_time = time.time()
func()
end_time = time.time()
print('spend is {}'.format(end_time - start_time))
return wrapper
def foo():
print('foo..')
time.sleep(3)
if __name__ == '__main__':
foo = showtime(foo) # decorator的原理就是闭包
foo()
闭包:
闭包就是外部函数的返回值调用的是内部函数,内部函数的变量调用了外部函数的临时变量。
在计算机科学中,闭包(英语:Closure),又称词法闭包(Lexical Closure)或函数闭包(function closures),是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例。
闭包解释:
程序被加载到内存执行时,函数定义的代码被存放在代码段中。函数被调用时,会在栈上创建其执行环境,也就是初始化其中定义的变量和外部传入的形参以便函数进行下一步的执行操作。当函数执行完成并返回函数结果后,函数栈帧便会被销毁掉。函数中的临时变量以及存储的中间计算结果都不会保留。下次调用时唯一发生变化的就是函数传入的形参可能会不一样。函数栈帧会重新初始化函数的执行环境。
# 修改闭包变量的实例
# outer是外部函数 a和b都是外函数的临时变量
def outer(a):
b = 10 # a和b都是闭包变量
c = [a] # 这里对应修改闭包变量的方法2
# inner是内函数
def inner():
# 内函数中想修改闭包变量
# 方法1 nonlocal关键字声明
nonlocal b
b += 1
# 方法二,把闭包变量修改成可变数据类型 比如列表
c[0] += 1
print(c[0])
print(b)
return inner
if __name__ == '__main__':
demo = outer(5)
demo() # 6 11