装饰器:
定义:本质是函数,为其他函数添加附加功能。
原则:1.不能修改被装饰的函数的源代码
2.不能修改被装饰函数的调用方式
实现装饰器的知识储备:装饰器=高阶函数+嵌套函数
1.函数即变量
2.高阶函数
a:把一个函数名当做实参传给另一个函数---->为了不能修改被装饰的函数的源代码,为函数增加功能
b:返回值中包含函数名------>为了不能修改被装饰函数的调用方式
3.嵌套函数
a.嵌套函数即在函数内部定义函数并使用
b.外部函数的变量可以被内部函数所使用,但不能被内部函数修改,若要修改需要添加关键字nonlocal
def foo(): outer_name="foo" print("in the foo") def bar(): nonlocal outer_name outer_name="bar" ##若不声明nonlocal,就无法修改外部的变量 print("in the bar") bar()#函数内部定义函数并使用 print("the outer_name is {_out_name}".format(_out_name=outer_name)) foo() >>>in the foo >>>in the bar >>>the outer_name is bar
装饰器语法总结:
def myDecorator(...): # 定义装饰器,可能带参数 def decorator(func): # 装饰器核心,以被装饰的函数对象为参数,返回装饰后的函数对象 def wrapper(*args, **kvargs): # 装饰的过程,参数列表适应不同参数的函数 ... # 修改函数调用前的行为 func(*args, **kvargs) # 调用函数 ... # 修改函数调用后的行为 return wrapper return decorator @myDecorator(...): # 给函数加上装饰器 def myFunc(...): # 自己定义的功能函数
不带参数的装饰器:
import time def timer(func): #timer(test1) func=test1 用于把被装饰函数传递给装饰器 def deco(*args,**kwargs): ##用于实现装饰器功能,附加功能 start_time=time.time() func(*args,**kwargs) #run test1() stop_time = time.time() print("the func run time is %s" %(stop_time-start_time)) return deco ##返回被装饰函数的地址,这样就保持了原有的调用方式 @timer #test1=deco=timer(test1) def test1(): time.sleep(1) print('in the test1') @timer # test2 = deco=timer(test2) test2(name) =deco(name) def test2(name,age): time.sleep(1) print("test2:",name,age) test1() test2("paul",22)
带参数的装饰器:
import time def time_log(log_type):##用于定义参数 """ timer为装饰器的核心代码 """ def timer(func): #timer(test1) func=test1 用于把被装饰函数传递给装饰器 def deco(*args,**kwargs): ##用于实现装饰器功能,附加功能 start_time=time.time() func(*args,**kwargs) #run test1() stop_time = time.time() if log_type=="auto": print("the func auto run time is %s" %(stop_time-start_time)) elif log_type=="manual": print("the func manual run time is %s" % (stop_time - start_time)) return deco ##返回被装饰函数的地址,这样就保持了原有的调用方式 return timer @time_log(log_type="auto") def test1(): time.sleep(1) print('in the test1') @time_log(log_type="manual") def test2(name,age): time.sleep(1) print("test2:",name,age) test1() test2("paul",22)