Python 装饰器补充

定义了一些函数,这些函数都要被外部所调用,但是这些函数在被调用之前,都有些相同的功能需要被实现,在这种情况下,装饰器是最好的解决方案:

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()
原文地址:https://www.cnblogs.com/python-study/p/5652072.html