美文网首页颠覆你的Python实践
【Python实践】_装饰器

【Python实践】_装饰器

作者: 大婶N72 | 来源:发表于2020-03-02 00:01 被阅读0次

    真正的稳定,是自己不断成长,不断寻找新的空间。与其要稳定,不如开始拥抱这个变化的时代,让自己准备好。


    python实践

    【目录】Python实践

    【写在前面】:
    曾经在面试的时候问过很多人“什么是装饰器?”,但是都没有得到一个很简洁明了的答案,希望这篇文章能使你对装饰器有个比较清楚、简洁的认识。
    【材料】:
    参考材料 《Python进阶》

    【Step1】:什么是装饰器?
    从字面意思来理解,装饰+器,装饰我们都知道,是在原有基础上增加某些功能,达到一定的效果,python中的装饰器也是在原来函数(类)上增加一些特殊的功能,但是并不是直接去修改原来的函数(类),而是新写一个函数,这个函数的功能就是在对原函数(类)二次处理(并非重构)
    简单举例如下:

    # -*- coding: utf-8 -*-
    def greet(fun):
        def pre():
            print("I'm pre")
            t = fun()
            return t
        return pre
    
    
    @greet
    def test():
        return "I'm test"
    
    
    if __name__ == '__main__':
        print(test())
    

    运行结果如下:

    I'm pre
    I'm test
    

    上面的greet函数就是一个装饰器,其作用就是对test函数做装饰,在待装饰的函数前面使用@符号来调用装饰函数。
    【Step2】:对Step1的解释
    1、对函数的认识,通常def test()被叫做定义一个test函数,这其中test是函数名,当使用test()时表示在调用该函数,可以拿到return值,当使用test时并不会调用,只是将函数作为一个变量,可以赋值给其他变量,比如a,这样a变量就有了test函数的功能,而且两个函数名都指向该函数的内存地址(0x012B5618)。这里我们了解到原来函数不是只能直接被调用,函数名还能够作为参数使用,这一点很重要。

    def test():
        return "I'm test"
    
    
    if __name__ == '__main__':
        print(test())
        print(test)
        a = test
        print(a)
        print(a())
        del test
        print(a())
    

    运行结果如下:

    I'm test
    <function test at 0x00B25618>
    <function test at 0x00B25618>
    I'm test
    I'm test
    

    2、函数中定义函数
    函数out中包含子函数inner,调用out函数时,会return出该函数的输出,即“here is out...”,在out函数内部有print(inner())来打印inner函数的return结果,即“here is inner...”(如果没有这一句,是不会调用inner函数的),而由于inner函数是在out函数内部的,所以不能被单独调用。
    举例如下:

    def out():
        print("here is out...")
    
        def inner():
            return "here is inner..."
        print(inner())
    
    
    out()
    inner()
    

    运行结果如下:

    here is out...
    here is inner...
      File "D:/auto_case/DailyWork/test.py", line 10, in <module>
        inner()
    NameError: name 'inner' is not defined
    

    3、从函数中返回函数
    现实中很少会在函数中去执行一个函数,更多的时候是希望将内部函数作为外层函数的return值,所以我们可以这样改造,达到返回内层函数的效果
    (1).out函数,这个就是out的一个函数,return a
    (2).out1函数,内层inner1函数,在out1函数中使用inner1()调用inner1,返回inner1函数return的值;
    (3).out2函数,内层inner2函数,在out2函数中使用inner2将函数赋值给了变量c,返回函数c(注意不是函数c被调用的值);
    (4).out3函数是对out2函数的简写,功能一样;
    (5).在print中,重点是out3()是一个函数,所以要得到函数返回值,就需要在其后面加上小括号,达到调用函数的效果,即out3()()。
    举例如下:

    # -*- coding: utf-8 -*-
    def out():
        a = "test"
        return a
    
    
    def out1():
        def inner1():
            return "here is inner..."
        b = inner1()
        return b
    
    
    def out2():
        def inner2():
            return "here is inner2..."
        c = inner2
        return c
    
    
    def out3():
        def inner3():
            return "here is inner3..."
        return inner3
    
    
    print(out())
    print(out1())
    print(out2())
    d = out2()
    print(d())
    print(out3())
    print(out3()())
    

    运行结果如下:

    test
    here is inner...
    <function out2.<locals>.inner2 at 0x01A3D8E8>
    here is inner2...
    <function out3.<locals>.inner3 at 0x01A3D618>
    here is inner3...
    

    4、将函数名作为参数传递给其他函数
    函数名可以代表函数,也可以赋值,所以能够作为参数专递到函数中去,在函数中只要在参数后面加上小括号,就拥有了该函数的功能。我在下面的函数中加了步骤输出,读者可以比较清楚的知道函数是如何调用的。
    举例如下:

    # -*- coding: utf-8 -*-
    def test():
        print("step 4")
        return "I'm test"
    
    
    def greet(fun):
        print("step 1")
        
        def pre():
            print("step 2")
            print("I'm pre")
            t = fun()
            return t
        print("step 3")
        return pre
    
    
    print(greet(test))
    print(greet(test)())
    
    

    运行结果如下:

    C:\Users\54788\AppData\Local\Programs\Python\Python35-32\python3.exe D:/auto_case/DailyWork/test.py
    step 1
    step 3
    <function greet.<locals>.pre at 0x01C0D588>
    ~~~~~~虚拟分割线~~~~~~~
    step 1
    step 3
    step 2
    I'm pre
    step 4
    I'm test
    
    Process finished with exit code 0
    
    

    5、装饰器标识符“@”,使用@装饰器名在待装饰函数前,即可完成不修改待装饰函数的情况下,修改函数的功能,注意装饰器必须在被装饰函数前定义。
    【Step3】:应用场景举例
    鉴权在打开页面和登录中的使用

    # -*- coding: utf-8 -*-
    def auth(fun):
        def base_auth(*param):
            if param[0] == '123%$&*sdhjd':
                return fun(*param)
            else:
                return no_auth()
        return base_auth
    
    
    def no_auth():
        return "you have no auth"
    
    
    @auth
    def open_page(param):
        return "begin to open page..." + str(param)
    
    
    @auth
    def login(param1,param2):
        return "begin to login..." + str(param2)
    
    
    print(open_page('123%$&*sdhjd'))
    print(open_page('123%$&*'))
    print(login('123%$&*sdhjd', 'test'))
    print(login('123%$&*', 'test'))
    
    

    相关文章

      网友评论

        本文标题:【Python实践】_装饰器

        本文链接:https://www.haomeiwen.com/subject/vwinchtx.html