闭包函数
内部函数包含对外部作用域而非全剧作用域名字的引用,该内部函数称为闭包函数
判断是否是闭包函数 ___closure___ 有cell 即闭包函数 None 则不是
#输出的__closure__有cell元素 :是闭包函数
def func():
name = 'a'
def inner():
print(name)
print(inner.__closure__)
return inner
f = func()
f()
#输出的__closure__为None :不是闭包函数
name = 'aa'
def func2():
def inner():
print(name)
print(inner.__closure__)
return inner
f2 = func2()
f2()
def func(): name = 'a' def inner(): print(name) return inner f = func() print(f) f()
装饰器
装饰器的本质:一个闭包函数
装饰器的功能:在不修改原函数及其调用方式的情况下对原函数功能进行扩展
import time def wrapper(func): def inner(*args, **kwargs): start = time.time() ret = func(*args, **kwargs) end = time.time() print(end - start) return ret return inner @wrapper def func(): time.sleep(1) print(111) print(func())
查看函数的相关信息 def index(): '''这是一个主页信息''' print('from index') print(index.__doc__) #查看函数注释的方法 print(index.__name__) #查看函数名的方法
避免 查看函数的一些信息的方法在此处失效
from functools import wraps def deco(func): @wraps(func) def wrapper(*args, **kwargs): print('函数之前的装饰') ret = func(*args, **kwargs) print('函数之后的装饰') return ret return wrapper @deco def func(): '''函数的注释信息''' print('函数') print(func()) print(func.__name__) print(func.__doc__)
开放封闭原则:
任何一个程序,都应该对拓展是开放的,对修改是封闭的
装饰器固定格式 def timer(func): def inner(*args,**kwargs): '''执行函数之前要做的''' re = func(*args,**kwargs) '''执行函数之后要做的''' return re return inner
多个装饰器装饰一个函数
def wrapper1(func): def inner(): print('wrapper1 ,before func') func() print('wrapper1 ,after func') return inner def wrapper2(func): def inner(): print('wrapper2 ,before func') func() print('wrapper2 ,after func') return inner @wrapper2 @wrapper1 def f(): print('in f') f()
带参数的装饰器
def outer(flag): def wrapper(func): def inner(*args, **kwargs): if flag: print('''执行函数之前要做的''') re = func(*args, **kwargs) if flag: print('''执行函数之后要做的''') return re return inner return wrapper @outer(True) def func(): print('111') return 'aaa' print(func())