• 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()
  • 相关阅读:
    MySQL 5.6 中 TIMESTAMP 的变化
    NetWork
    Esper
    maven nexus linux私服搭建
    file not found app文件
    设计模式之十五:訪问者模式(Visitor Pattern)
    邻接表 几篇不错的解说
    自己定义带三角形箭头的TextView
    linux程序调试命令addr2line之入门简单介绍(本文先不聊gdb调试)
    AndroidManifest 中android:exported
  • 原文地址:https://www.cnblogs.com/python-study/p/5652072.html
Copyright © 2020-2023  润新知