zoukankan      html  css  js  c++  java
  • Python中装饰器的用法

    1. 定义:
      1. 装饰器本身就是一个函数
      2. 为其他函数提供附加功能
        1. 不改变源代码
        2. 不改变原调用方式
      3. 装饰器=高阶函数+嵌套函数
    2. 知识点:
      1. 函数本身就是一个变量(意味着可以被复制给一个变量:test=test(1) )
      2. 高阶函数
        1. 把函数名当成一个实参传递给另一个函数func(test1) (不改变源代码的前提下添加代码)
        2. 返回值中包含函数名return deco (不改变函数的调用方式)
      3. 嵌套函数:函数中加入新的函数def func1(): def func2():
    3. 典型结构:   
    1 def func1(test):
    2     def deco():
    3         #progress
    4     return deco#返回函数的地址,达到不改变调用方式的目的
    View Code

    完整程序:

    # __Author__Panda-J____
    
    import time
    
    
    def timer(func):  # for test1 & 2
        start_time = time.time()
        func()  # run func and test its running time
        end_time = time.time()
        print("this func running time is %s" % (end_time - start_time))
    return func
    
    @timer
    def test1():
        time.sleep(1)
        print("this is test1")
    
    
    @timer
    def test2():
        time.sleep(1)
        print("this is test2")
    
    
    test1()
    test2()
    View Code

     带参数的装饰器:

     1 # __Author__Panda-J____
     2 
     3 import time
     4 
     5 
     6 def timer(func):  # for test1 & 2
     7     def deco(*args,**kwargs):#不定参数
     8         start_time = time.time()
     9         func(*args,**kwargs)  # run func and test its running time
    10         end_time = time.time()
    11         print("this func running time is %s" % (end_time - start_time))
    12     return deco
    13 
    14 @timer
    15 def test1():
    16     time.sleep(1)
    17     print("this is test1")
    18 
    19 
    20 
    21 @timer
    22 def test2(arg1):
    23     time.sleep(1)
    24     print("this is test2,",arg1)
    25 
    26 
    27 print(test1())
    28 test2("name")

      本段程序的结果是

    this is test1
    this func running time is 1.000265121459961
    None
    this is test2, name
    this func running time is 1.0000722408294678

      问题:

      1 为什么print(test1)会为None,原因是因为在装饰器中没有返回(return)任何数值给到test1中。没有可以打印的内容。

      2 在28行中,test2有一个位置参数name传给了装饰器deco中,此处的arg=“name”

    如果装饰器本身也带参数的情况:

        需求:三层网页,分别为index,home,bbs。在登陆home和bbs页面的时候需要输入不同的用户名和密码,正确方可运行对应函数。

        思路

        1. 定义三个函数
        2. 加装饰器
        3. 用不同的用户名和密码(一个为本地Local,一个为ldap)

    完整程序

    # __Author__Panda-J____
    #语法糖

    import time
    user="jiang"
    pssw="123"
    def auth(auth_type):#多加了一层函数进行关键字嵌套
    print("auth func is",auth_type)
    def outer_wrapper(func):#相当于没有装饰器参数时候的那一层
    def wrapper(*args,**kwargs):#进行函数的装饰
    if auth_type=="local":#使用本地用户名和密码
    user_name=input("user_name:").strip()
    password=input("paassword:").strip()
    if user_name==user and password==pssw:#判定用户名和密码驶入正确
    print("33[32;1mUser authorized33[0m")
    return func(*args, **kwargs)#返回函数进行打印,如果没有这一行,不会执行home和bbs函数中的打印程序,home()将为None,因为没有返回任何内容
    else:#用户名和密码输入不正确
    exit("33[31;1mUser failed33[0m")
    elif auth_type=="ldap":#使用ldap的密码
    print("plz use ldap password")
    return wrapper
    return outer_wrapper
    def index():
    print("welcome index")
    @auth(auth_type="local")#home
    def home():
    print("welcome home")
    return "home is best"
    @auth(auth_type="ldap")
    def bbs():
    print("welcome bss")

    index()
    print(home())
    bbs()

    我所能理解的装饰器的应用场景和关键知识点都归纳了,欢迎各位指正。

             

  • 相关阅读:
    python解压缩rar,zip文件的正确姿势
    tensorflow1.x及tensorflow2.x不同版本实现验证码识别
    qt5.6.3下使用firebird
    Python3.6下的Requests登录及利用Cookies登录
    c++实现全密码生成
    android中利用HttpURLConnection进行Get、Post和Session读取页面。
    Freebsd10.3 Nginx多版本PHP
    Freebsd10.3(FreeBSD11 Beta1)使用手记
    Eclipse导入的User Libarary
    MySQL zip版本安装
  • 原文地址:https://www.cnblogs.com/BigJ/p/7396144.html
Copyright © 2011-2022 走看看