zoukankan      html  css  js  c++  java
  • python中装饰器进化史

    思想:不要重复自己的工作,Don't repeat yourself
    目的:我有一个函数countdown,现在想统计一下这个函数的运行时长。改装之后呢,计时功能有了,运行时和改装前一样,改装前运行:countdown(100000000)

    第一种写法,初级写法:
     1 def countdown(n):
     2     while n>0:
     3         n-=1
     4 
     5 def wrapper(func,*args,**kwargs):
     6     start = time.time()
     7     result = func(*args, **kwargs)
     8     end = time.time()
     9     print(func.__name__, end - start)
    10     return result
    11 
    12 wrapper(countdown,100000000)
    使用之前:countdown(100000000)
    使用之后:wrapper(countdown,100000000)
    这样,功能增加增加后,函数运行的方式改变了,意思不清楚,别人看你的代码,容易产生误会,代码可读性下降!

    第二种,过度写法:
     1 def timethis(func):
     2     # @wraps(func)
     3     def wrapper(*args,**kwargs):
     4         start=time.time()
     5         result=func(*args,**kwargs)
     6         end=time.time()
     7         print(func.__name__,end-start)
     8         return result
     9     return wrapper
    10 
    11 def countdown(n):
    12     while n>0:
    13         n-=1
    14 
    15 # 1,对函数包装,装饰器本身就是一个函数
    16 countdown = timethis(countdown)
    17 # 2,这一步才执行函数
    18 countdown(100000000)
    # 使用之前:countdown(100000000)
    # 使用之后:countdown(100000000)
    总结:第二种写法,已经实现了要求的,符合要求,加了一行 countdown = timethis(countdown),哪个函数需要计时功能,用这个timethis包装一下就行了,但是有没有更优雅简洁的写法呢?

    第三种,究极写法:

     1 def timethis(func):
     2     # @wraps(func)
     3     def wrapper(*args,**kwargs):
     4         start=time.time()
     5         result=func(*args,**kwargs)
     6         end=time.time()
     7         print(func.__name__,end-start)
     8         return result
     9     return wrapper
    10 
    11 @timethis
    12 def countdown(n):
    13     while n>0:
    14         n-=1
    15 
    16 countdown(100000000)
    # 使用之前:countdown(100000000)
    # 使用之后:countdown(100000000)
    总结:这种写法和第二种写法,@timethis和countdown = timethis(countdown)功能是一样的,但是很显然@timethis更简洁,@是官方提供的友好的“语法糖”,也是为了能把装饰器表达的意思更清晰
    而实现装饰器的这个函数,timethis ,函数里面又定义了一个函数,这种特殊的函数,称为闭包
    全世界的程序员们联合起来吧!
  • 相关阅读:
    面向对象之绑定方法与非绑定方法
    Django-admin源码解析
    单例模式
    Django-admin管理工具
    Django-CBV
    叠加装饰器,三元表达,生成,调用,递归
    迭代器与生成器
    有参装饰器
    储备知识与装饰器
    文件修改
  • 原文地址:https://www.cnblogs.com/chaojiyingxiong/p/14815030.html
Copyright © 2011-2022 走看看