zoukankan      html  css  js  c++  java
  • python-装饰器

    ---恢复内容开始---

    装饰器:装饰器的本质就是一个函数,其主要目的就是装饰其他函数(为其他函数添加新功能)!

    装饰器的一些特性:

    • 不能修改被装饰函数的源代码
    • 被装饰函数的调用方式不能改变

    理解以下三点:

    • 函数即变量(函数名可以类比变量名,函数体可以类比变量的内容!)
    • 高阶函数:
      •   把一个函数的函数名作为实参传递给另外一个函数
      •        函数的返回值中包含函数名
    #满足两个条件之一的均称为高阶函数
    # def bar():      #传递函数名作为实参
    #     print("int the bar...")
    #
    # def outer(func):
    #     print("in the outer...")
    #     func()
    #
    # outer(bar)
    #传递函数名为实参,没有修改被装饰函数的源代码
    #返回函数名 def bar(): print("int the bar...") def outer(func): print("in the outer...") return func bar = outer(bar) bar() #返回函数名没有修改原函数的调用方式
      •   嵌套函数:在一个函数体中使用def语句定义另一个函数称为嵌套函数,注意不是调用

    装饰器==高阶函数+嵌套函数:

    1. 利用高阶函数(传递函数名为参数的特性)把要被装饰的函数,传递给装饰器函数以添加新的功能,并且不改变被装饰函数的源代码!
    2. 利用高阶函数(返回函数名),没有修改被装饰函数的调用方式.
    3. 利用嵌套函数把装饰器封装成一个函数,借助语法糖@调用。
    '''
    利用装饰器打印出函数的执行时间
    '''
    import time
    
    def timmer(func):
        def wrapper():
            start_time = time.time()
            func()
            stop_time = time.time()
            print("The func.__name__ running %s second" % (stop_time-start_time))
        return wrapper
    
    @timmer     #装饰器的语法糖,这句等价于test1 = timmer(test1)
    def test1():
        time.sleep(1)
    @timmer
    def test2(): #装饰器的语法糖,这句等价于test2 = timmer(test2),
        time.sleep(2)
    
    test1()  #原函数的源代码和调用方式均没有改变
    test2()


    上面的原函数及装饰器均没有参数,带参数的装饰器:

    '''
    利用装饰器打印出函数的执行时间
    '''
    import time
    
    def timmer(func):
        def wrapper(*args,**kwargs):   #被装饰函数的参数是传递给wrapper的,因此wrapper函数需要能接收参数
            start_time = time.time()
            func(*args,**kwargs)
            stop_time = time.time()
            print("The %s running %s second" % (func.__name__,stop_time-start_time))
        return wrapper
    
    @timmer     #装饰器的语法糖,这句等价于test = timmer(test1)
    def test1(name):
        print (name.center(50,"-"))
        time.sleep(1)
    @timmer
    def test2(name): #装饰器的语法糖,这句等价于test = timmer(test2),
        print(name.center(50,"-"))
        time.sleep(2)
    
    test1("LFY")  #原函数的源代码和调用方式均没有改变
    test2("WXZ")


    有一个需求,对于不同的被装饰函数,根据传入的参数不同,添加不同的功能!

    两种方法:

    • 再写一个装饰器(不推荐)。
    • 第二种方法根据参数的不同,选择不同的装饰器。

    对于test1函数和test2函数上面的装饰器,都添加显示执行时间的功能;现在有如下需求:对于test1不变,仍然添加函数执行时间的功能,对于test2函数添加打印出函数的开始执行时间和结束的时间。

    # *-*coding:utf-8 *-*
    # Auth: wangxz
    import  time
    
    def timmer(type):   #就是在装饰器的外层在嵌套一个函数
        def out_wrapper(func):
            def wrapper(*args, **kwargs):
                if type == "one":
                    start_time = time.time()
                    func(*args, **kwargs)
                    stop_time = time.time()
                    print("The %s running %s second" % (func.__name__, stop_time - start_time))
                elif type == "two":
                    print("The %s runging start at %s" % (func.__name__, time.time()))
                    func(*args, **kwargs)
                    print("The %s runging staop at %s" % (func.__name__, time.time()))
            return wrapper
        return out_wrapper
    
    @timmer("one")  ##注意的是这个实参,传递给了那个形参
    def test1(name):
        print (name.center(50,"-"))
        time.sleep(1)
    
    @timmer("two") #
    def test2(name): #装饰器的语法糖,这句等价于test = timmer(test2),
        print(name.center(50,"-"))
        time.sleep(2)
    
    test1("WXZ")   #根据传递的语法糖的参数不同,选择不同的装饰器
    test2("LFY")     #

    这段函数代码的执行结果如下:

    #代码执行的结果如下:
    -----------------------WXZ------------------------
    The test1 running 1.0000572204589844 second
    The test2 runging start at 1524373351.098816
    -----------------------LFY------------------------
    The test2 runging staop at 1524373353.0989301
    
    Process finished with exit code 0

    需要注意的是:

        如果被装饰的函数有return返回值,那么在装饰器的wrapper()函数中,也需要使用return语句返回函数的结果。

    ---恢复内容结束---

  • 相关阅读:
    Delphi TStringList的用法
    Android Studio使用教程(一)
    如何在win7下安装和配置Android Studio
    python基础字符串单引号双引号和三引号
    同步和互斥
    posix多线程有感线程高级编程(条件变量)
    VMware网络配置详解
    posix多线程有感POSIX 线程间的内存可视性
    进程及相关API
    POSIX线程属性
  • 原文地址:https://www.cnblogs.com/wxzhe/p/8906641.html
Copyright © 2011-2022 走看看