定义了一些函数,这些函数都要被外部所调用,但是这些函数在被调用之前,都有些相同的功能需要被实现,在这种情况下,装饰器是最好的解决方案:
def f1(): print ("F1") def f2(): print ("F2")
在另一个模块中调用的时候
import s1 s1.f1() s1.f2()
执行结果:
F1
F2
这个时候,我们需要在f1,f2中分别添加打印日志的功能,于是,函数的定义变成了
def f1(): print ("log") print ("F1") def f2(): print ("log") print ("F2")
在模块中调用执行的结果是:
log
F1
log
F2
这个时候整个函数都要修改,工作量非常之大,于是想到了用一个函数来定义日志的打印功能
def log(): print ("log")
def f1(): log() print ("F1") def f2(): log() print ("F2")
通过这样改变代码,我们也可以实现功能,而且每次都只需要修改函数的内容即可。但是这样还是改变了f1,f2函数体的内容,违反了开放封闭原则(函数内的不要修改,函数外的可以修改)
def outer(func): def inner(): print ("log") func() return inner @outer #f1 = outer(f1) def f1(): print ("F1") @outer def f2(): print ("F2")
装饰器的内层原理:@outer有两个功能:1,自动执行outer函数,并且将其紧挨的下面的函数名f1传递给outer函数;2,将outer函数的返回值重新赋值给了f1函数
带返回值的装饰器
def outer(func): def inner(): print ("before") func() print ("after") return inner # @outer def f2(): print ("F2") return "SB"
在另一个模块调用,没有使用装饰器的前提下(有返回值):
r = s1.f2() print (r) 结果: F2 SB
添加了装饰器之后,代码改为下面的格式(没有记录返回值):
def outer(func): def inner(): print ("before") func() print ("after") return inner @outer def f2(): print ("F2") return "SB" 执行结果: before F2 after None
打印的结果跟我们需要的不一致(我们需要记录到返回值),于是重新修改了装饰器代码:
def outer(func): def inner(): print ("before") r = func() print ("after") return r return inner @outer def f2(): print ("F2") return "SB" 执行结果: before F2 after SB
定义带参数的装饰器
def outer(func): def inner(a): print ("before") r = func(a) print ("after") return r return inner @outer def f2(a): print (a) return "SB" 在模块中调用 r = s1.f2("ffffff") print (r) 执行结果: before ffffff after SB
双层装饰器
__author__ = 'Alex' #coding:utf-8 LOING_USER={"Is_login":False} def outer(func): def inner(*args,**kwargs): if LOING_USER['Is_login']: func() else: print ("Please login first!") return inner # def outer2(func): # def inner(*args,**kwargs): # if LOING_USER['Is_login']: # if LOING_USER.get("user_level") == 2: # func() # else: # print ("You do not have priviledge!") # else: # print ("Please login first!") # return inner def outer2(func): def inner(*args,**kwargs): if LOING_USER.get("user_level") == 2: func() else: print ("You do not have priviledge!") return inner @outer def check(): print ("welcome %s login" %LOING_USER['current_user']) # else: # print ("if you want to check,Please login first!") @outer2 @outer def manager(): # if LOING_USER['Is_login']: print ("welcome %s login" %LOING_USER['current_user']) print ("You level is %s" %LOING_USER['user_level']) # else: # print ("Please login first!") def login(): username = input("Please input the username: ") if username == "alex": LOING_USER["Is_login"] = True LOING_USER["current_user"] = username print ("You login success") elif username == "admin": LOING_USER["Is_login"] = True LOING_USER["current_user"] = username LOING_USER["user_level"] = 2 else: print ("You are invalid") def main(): while True: print(''' 1.登录 2.后台管理 3.检查 ''') inp = input ("Please input the choise:") if inp == '1': login() elif inp == '2': manager() elif inp == '3': check() print (LOING_USER) main()