Python入门学习(九)Python的高级语法与用法(四)装饰器
一、从一个简单问题引入装饰器的作用由来
import time def f1(): print(time.time()) #输出unix时间戳 print("This is the f1 function.") f1() #f1()函数很简单,实现一句话的打印 #如果要获取执行函数的时间,则按上述加入time()代码 #如果有很多函数都有增加时间戳的需求,如下面的f2() def f2(): print("This is the f2 function.") #难道都进入函数定义去修改代码吗? #函数理应对修改是封闭的,对扩展是开放的 #那么按如下思路则可以实现扩展 #将扩展功能单独作为一个函数,将需要扩展功能的原函数作为参数传递进去执行 def print_current_time(func): #func为需要扩展增加时间戳功能的函数名 print(time.time()) func() #那么对于f2,需要扩展功能,则如下实现 print_current_time(f2) #但对于上述解决方案,扩展功能单独设置,没有与原函数整合 #本质上,上述print_current_time()函数的实现和下面代码一样 #print(time.time()) #f2() #那么如何更好地作为原函数的扩展功能,则引入了装饰器这个概念
二、装饰器
import time #装饰器的基本结构,类似于闭包即函数内部包含函数,并且返回的是函数名 def decorator(func): def wrapper(): print(time.time()) func() return wrapper def f1(): print("This is the f1 function.") f = decorator(f1) f()
对于上述代码,实现了装饰器的代码,但也并未直接将扩展功能和原始函数绑定关联
仍然需要通过f = decorator(f1)这样的代码去捆绑实现
python中通过@装饰器名实现关联
import time #装饰器的基本结构,类似于闭包即函数内部包含函数,并且返回的是函数名 def decorator(func): def wrapper(): print(time.time()) func() return wrapper @decorator def f1(): print("This is the f1 function.") f1() #等同于f = decorator(f1) f()
上述示例中f1()函数是没有参数的,如果带有参数,那么装饰器需要做哪些改动呢?
一个参数的情况:
import time #一个参数的情况 #装饰器的基本结构,类似于闭包即函数内部包含函数,并且返回的是函数名 def decorator(func): def wrapper(fn): print(time.time()) func(fn) return wrapper @decorator def f1(func_name): print("This is the f1 function named " + func_name) f1("test func") #等同于f2 = decorator(f1) f2("test func")
对于同一装饰器,各类参数数量不一的函数都需要用到,则需要用可变参数去实现:
import time #一个参数的情况 #装饰器的基本结构,类似于闭包即函数内部包含函数,并且返回的是函数名 def decorator(func): def wrapper(*args): print(time.time()) func(*args) return wrapper @decorator def f1(func_name): print("This is the f1 function named " + func_name) @decorator def f2(a, b): print("a + b = " + str(a+b)) print("This is the f2 function!") f1("TEST FUNC") f2(30, 50)
进一步如果涉及到关键字可变参数,则如下:
import time #一个参数的情况 #装饰器的基本结构,类似于闭包即函数内部包含函数,并且返回的是函数名 def decorator(func): def wrapper(*args, **kw): print(time.time()) func(*args, **kw) return wrapper @decorator def f1(func_name): print("This is the f1 function named " + func_name) @decorator def f2(a, b): print("a + b = " + str(a+b)) print("This is the f2 function!") @decorator def f3(func_name1, func_name2, **kw): print("This is the f3 function " + func_name1) print("This is the f3 function " + func_name2) for k, v in kw.items(): print(k, ":", v) f1("func1 name") f2(12, 38) f3("test func1", "test func2", a = 1, b = 2, c = "ABC")
浙公网安备 33010602011771号