实现装饰器的知识储备:
示例: def f1(): print("f1") 1、函数即“变量” #上面的示例中,函数f1为变量,它指向内存地址。而f1()表示函数执行。 2、高阶函数 a:把一个函数名当做实参传给另外一个函数(在不修改被装饰函数源代码的情况下为其添加功能)。 b:返回值中包含函数名(不修改函数的调用方式)。 3、嵌套函数 将一个函数放在另外一个函数里面。 装饰器 = 高阶函数 + 嵌套函数
装饰器定义:本质是函数。(装饰其他函数)就是为其他函数添加附加功能。
装饰器原则:
1、不能修改被装饰的函数的源代码。
2、不能修改被装饰的函数的调用方式。
装饰器代码剖析:
假如A公司有这么一个需求,公司临时规定将某块业务加上访问权限,因为代码太多,又不想改变原有封装好的代码,于是码农提出一个解决方法:装饰器。
原始代码:
def f1(): #print("welcome to login...") #需求是在这块加上验证 print("f1...") f1() #执行函数
添加一个验证模块后,功能是实现了,但是改变了原有的调用方式:
#!/usr/bin/env python # -*- coding:utf-8 -*- #author chenjing def auth_login(func): #func = f1 def inner(): print("welcome to login...") #验证的内容加载这里 func() #func() = f1(),相当于执行f1() return inner #返回inner函数体 def f1(): #print("welcome to login...") #需求是在这块加上验证 print("f1...") result = auth_login(f1) #等于inner函数(包括它下面那一段代码) result() #执行函数
继续修改,保证原有的调用方式不受影响。
#!/usr/bin/env python # -*- coding:utf-8 -*- #author chenjing def auth_login(func): #func = f1 def inner(): print("auth user ...") #认证模块 func() #func() = f1(),相当于执行f1() return inner #返回inner函数体 @auth_login #@auth_login是Python默认封装好的一种方法,它就是装饰器,功能相当于result = auth_login(f1) def f1(): print("I'm f1") f1() #执行函数
输出结果:
auth user ... I'm f1
到目前为止,f1业务好像已经完成了,这时f2业务又提了一个需求,f2调用时,需要往函数里面传递一个参数。coding...
那么怎么办呢?那我们定义另外一个装饰器,而这个装饰器是可以接收参数的。
#!/usr/bin/env python # -*- coding:utf-8 -*- #author chenjing def auth_login(func): #func = f1 def inner(): print("auth user ...") #认证模块 func() #func() = f1(),相当于执行f1() return inner #返回inner函数体 def auth_login_arg(func): def inner(arg): print("auth user arg...") func(arg) return inner @auth_login #@auth_login是Python默认封装好的一种方法,相当于result = auth_login(f1) def f1(): print("I'm f1") f1() #执行函数 @auth_login_arg #调用新装饰器 def f2(arg): #参数 print("I'm f2",arg) f2("new programs") #传入参数
输出结果:
auth user ... I'm f1 auth user arg... #请看f2函数的输出 I'm f2 new programs
到目前为止,f2业务好像已经完成了,这时f3业务又提了一个需求,f3调用时,需要往函数里面传递几个参数。coding...
这。。。程序员果然不是人干的。。我们还是看下面代码吧。
#!/usr/bin/env python # -*- coding:utf-8 -*- #author chenjing def auth_login(func): #func = f1 def inner(): print("auth user ...") #认证模块 func() #func() = f1(),相当于执行f1() return inner #返回inner函数体 def auth_login_arg(func): def inner(arg): print("auth user arg...") func(arg) return inner def auth_login_args(func): def inner(*args,**kwargs): #动态参数 print("auth user...") #认证模块 func(*args,**kwargs) #动态参数 return inner @auth_login #@auth_login是Python默认封装好的一种方法,相当于result = auth_login(f1) def f1(): print("I'm f1") f1() #执行函数 @auth_login_arg #调用新装饰器 def f2(arg): #参数 print("I'm f2",arg) f2("new programs") #传入参数 @auth_login_args def f3(name,age): print("I'm f3...",name,age) f3("Colin Chen",18)
输出结果:
auth user ... I'm f1 auth user arg... I'm f2 new programs auth user... I'm f3... Colin Chen 18
完美。需求都完成了,心情那叫一个好。