闭包 & 装饰器
开放封闭原则
- 开放:对于添加新功能是开放的
- 封闭:对于修改原功能是封闭的
闭包
概念
内部函数包含对外部作用域而非全剧作用域变量的引用,则称该内部函数称为闭包函数。
判断方法
输出的__closure__
是否有cell元素
作用
示例
1 2 3 4 5
| def foo(): x = 1 def bar(y): return x+y return bar
|
装饰器(闭包应用)
作用
在不更改原函数调用方式的前提下对原函数添加新功能
原理
利用闭包原理,通过在内部函数中调用外部函数的变量,实现在不改变原函数调用方式的前提下对原函数添加新功能。
种类
1 2 3 4 5 6 7 8 9 10 11 12
| def deco(f): def wrapper(): """原函数前添加的功能""" f() """原函数后添加的功能""" return wrapper
def func(): print('这是原函数!')
func = deco(func) func()
|
1 2 3 4 5 6 7 8 9 10 11 12
| def deco(f): def wrapper(): """原函数前添加的功能""" f() """原函数后添加的功能""" return wrapper
@deco # ——>此处效果等同于 func = deco(func) def func(): print('这是原函数')
func()
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| def deco(f): def wrapper(): """原函数前添加的功能""" res = f() """原函数后添加的功能""" return res return wrapper
@deco def func(): print('这是原函数')
func()
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| def deco(f): def wrapper(*args,**kwargs): """原函数前添加的功能""" res = f(*args,**kwargs) """原函数后添加的功能""" return res return wrapper
@deco def func(*args,**kwargs): print('这是原函数')
func(*args,**kwargs)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| def deco(f): def outer_wrapper(*args,**kwargs): def inner_wrapper(*args,**kwargs): """原函数前添加的功能""" res = f(*args,**kwargs) """原函数后添加的功能""" return res return inner_wrapper return outer_wrapper
@deco def func(*args,**kwargs): print('这是原函数')
func(*args,**kwargs)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| def deco1(f): def wrapper(*args,**kwargs): """原函数前添加的功能""" res = f(*args,**kwargs) """原函数后添加的功能""" return res return wrapper
def deco2(f): def wrapper(*args,**kwargs): """原函数前添加的功能""" res = f(*args,**kwargs) """原函数后添加的功能""" return res return wrapper
@deco1 # 其次执行 @deco2 # 首先执行 def func(*args,**kwargs): print('这是原函数')
func(*args,**kwargs)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| from functools import wraps
def deco(func): @wraps(func) #加在最内层函数正上方 def wrapper(*args,**kwargs): return func(*args,**kwargs) return wrapper
@deco def origin_func(): ''' 这是原函数的注释 :return: ''' print('这是原函数')
print(origin_func.__name__) >>> origin_func
print(origin_func.__doc__) >>> 这是原函数的注释 >>> :return:
|