• python中的装饰器理解


    python装饰器(fuctional decorators)就是用于拓展原来函数功能的一种函数,目的是在不改变原函数名(或类名)的情况下,给函数增加新的功能。 

    这个函数的特殊之处在于它的返回值也是一个函数,这个函数是内嵌“原“”函数的函数。

    之前拓展函数的做法是侵入原函数进行拓展修改,例如:

    原始函数:

          import time

      def f():
        print("hello")
        time.sleep(1)
        print("python")  
     
    修改为记录下这个函数执行的总时间,改动原来的代码:
       
          import time
     
         def f():

              begintime = time.time()
              print("hello")
              time.sleep(1)
         print("python")
              endtime = time.time()

              totaltime = (endtime - begintime )*1000
              print("time is %d ms" %totaltime )

    使用闭包函数的用法如下:

    import time

    def test(func):

      begintime = time.time()

      f()

      endtime = time.time()

      totaltime = (endtime - begintime) * 1000

      print("执行时间:%d ms"%tataltime)

    def f():

      print("hello")

      time.sleep(1)

      print("python")

    if __name == "__main__":

      test(f)

    这种方式的缺点是:但是想要拓展这一千万个函数功能,就是要执行一千万次test()函数。

    使用装饰器来实现如下:

    import time

    def test(f):

      def func():

        begintime = time.time()

        f()

        endtime = time.time()

        totaltime = (endtime-begintime) * 1000

        print("执行时间:%d ms"%tataltime)

      return func

    @test

    def f():

      print("hello")

      time.sleep(1)

      print("python")

    if __name == "__main__":

      f()

    这里的test函数就是最原始的装饰器,它的参数是一个函数,然后返回值也是一个函数。其中作为参数的这个函数f()就在返回函数func()的内部执行。然后在函数f()前面加上@test,

    f()函数就相当于被注入了计时功能,现在只要调用f(),它就已经变身为“新的功能更多”的函数了(不需要重复执行原函数)。 

    扩展1:带有固定参数的装饰器

    import time

    def test(f):

      def func(a,b):

        begintime = time.time()

        f(a,b)

        endtime = time.time()

        totaltime = (endtime-begintime) * 1000

        print("执行时间:%d ms"%tataltime)

      return func

     @test

    def f(a,b):

      print("hello")

      time.sleep(1)

      print("python")

      time.sleep(1)

      print(a+b)

     if __name == "__main__":

      f(3,4)

    扩展2:无固定参数的装饰器:

    import time

    def test(f):

      def func(*args,**kwargs):

        begintime = time.time()

        f(*args,**kwargs)

        endtime = time.time()

        totaltime = (endtime-begintime) * 1000

        print("执行时间:%d ms"%tataltime)

      return func

    @test

    def f(a,b):

      print("hello")

      time.sleep(1)

      print("python")

      time.sleep(1)

      print(a+b)

    @test

    def f2(a,b,c):

      print("hello")

      time.sleep(1)

      print("python")

      time.sleep(1)

      print(a+b+c)

     if __name == "__main__":

      f(3,4)

      f2(5,6,7)

    扩展3:使用多个装饰器装饰一个函数

    import time

    def test1(f):

      def func(*args,**kwargs):

        print("test1")

        begintime = time.time()

        f(*args,**kwargs)

        endtime = time.time()

        totaltime = (endtime - begintime) * 1000

        print("执行时间:%d ms"%tataltime)

        print("test1 end")

      return func

    def test2(f):

      def func(*args,**kwargs)

        print("test2 begin")

        f(*args,**kwargs)

        print("test2 end")

      return func

    @test1

    @test2

    def f(a,b):

      print("hello")

      time.sleep(1)

      print("python")

      time.sleep(1)

      print(a+b+c)

    if __name__ == "__main__":

      f(3,4)

    执行结果:

     test1

     test2 begin

    hello
    python
    7
    test2 end
    执行时间:%d ms"%tataltime
    test1 end

    装饰器调用顺序

    装饰器是可以叠加使用的,那么使用装饰器以后代码是啥顺序呢?

    对于Python中的”@”语法糖,装饰器的调用顺序与使用 @ 语法糖声明的顺序相反。

    在这个例子中,”f(3, 4) = test1(test2(f(3, 4)))”。

    Python内置装饰器

    在Python中有三个内置的装饰器,都是跟class相关的:staticmethod、classmethod 和property。

    • staticmethod 是类静态方法,其跟成员方法的区别是没有 self 参数,并且可以在类不进行实例化的情况下调用
    • classmethod 与成员方法的区别在于所接收的第一个参数不是 self (类实例的指针),而是cls(当前类的具体类型)
    • property 是属性的意思,表示可以通过通过类实例直接访问的信息
     

      

  • 相关阅读:
    Linq 入门系列 [Take,Skip,TakeWhile,SkipWhile]篇
    SqlString 引发的思考
    DLINQ
    Wrf 格式播放器
    仙剑奇侠传4序列号
    Asp.Net程序性能 浅谈
    Linq 扩展函数的应用
    正则表达式积累
    ajax 之取消服务器任务[转]
    Linq 演变的过程(delegate => Lamb => Linq)
  • 原文地址:https://www.cnblogs.com/jiangyuhu/p/11915662.html
Copyright © 2020-2023  润新知