zoukankan      html  css  js  c++  java
  • 装饰器从入门到精通

    装饰器从入门到精通:
    1.背景:年底到了,又要发年终奖了,可是怎么发比较好呢?
      你碰到了一个不懂技术的老大,老大说了,把大家把写得最为
      得意的一段代码拿出来跑时间,咱们凭实力说话!!!于是乎老板
      把测试时间的任务交给你了,那么问题来了,到底怎么解决好呢?

    2.于是乎,经过仔细思考你想到了一个方案,以前学数据结构的时候不是
      测试代码效率的办法:引用系统自带的时间模块即可:

      import time

      start = time.time()
      func()
      end = time.time()
      print(end - start)

    3.开放封闭原则:
      开放:对扩展是开放的
      封闭:对修改是封闭的
    4.好了不废话了,很显然,上面的代码是不满足这个原则的,接下来
      今天的主角登场了,装饰器!!!
    5.初识装饰器:

     1 import time
     2 
     3 
     4 def timmer(f):
     5     def inner():
     6         start = time.time()
     7         f()
     8         end = time.time()
     9         print(end - start)
    10 
    11     return inner
    12 
    13 
    14 def func():
    15     time.sleep(0.1)
    16     # 时间太短无法测试 所以sleep一下
    17     print("hello world")
    18 
    19 
    20 func = timmer(func)
    21 # 这里面讲func作为参数传到里面去执行了一趟!!!
    22 # 返回的func实际上是inner
    23 func()
    24 """
    25 hello world
    26 0.10023927688598633
    27 """
    View Code

    实际上这就是一个闭包嘛,地球人真麻烦取这么多名字干嘛!!!

    6.语法糖
      老是这么写:func = timmer(func),实在是繁琐,于是呢人们又发明了一个
      新的写法来代替上面这句话:在被装饰的函数前面加上@起装饰作用的函数
      上面这个就写成这样了:

     1 import time
     2 
     3 
     4 def timmer(f):
     5     def inner():
     6         start = time.time()
     7         f()
     8         end = time.time()
     9         print(end - start)
    10 
    11     return inner
    12 
    13 
    14 @timmer  # 相当于 func = timmer(func)
    15 def func():
    16     time.sleep(0.1)
    17     # 时间太短无法测试 所以sleep一下
    18     print("hello world")
    19 
    20 
    21 func()
    22 """
    23 hello world
    24 0.10023927688598633
    25 """
    View Code

    7.参数问题

      如果被装饰的函数里面有参数怎么办?装饰之后的func实际上是inner,而func又在

    inner里面执行,所以我把参数给inner,顺便再返回一下就可以了。

     1 import time
     2 
     3 
     4 def timmer(f):
     5     def inner(*args, **kwargs):
     6         start = time.time()
     7         ret = f(*args, **kwargs)
     8         end = time.time()
     9         print(end - start)
    10         return ret
    11 
    12     return inner
    13 
    14 
    15 @timmer  # 相当于 func = timmer(func)
    16 def func(a, b):
    17     time.sleep(0.1)
    18     # 时间太短无法测试 所以sleep一下
    19     print("hello world")
    20     return a + b
    21 
    22 
    23 a = func(1, 2)
    24 print(a)
    25 """
    26 hello world
    27 0.10096383094787598
    28 3
    29 """
    View Code

    8.装饰器公式 ===>万能金刚

     1 import time
     2 
     3 
     4 def outer(f):
     5     def inner(*args, **kwargs):
     6         start = time.time()
     7         ret = f(*args, **kwargs)
     8         end = time.time()
     9         print(start - end)
    10         return ret
    11 
    12     return inner
    13 
    14 
    15 @outer
    16 def func():
    17     pass
    View Code

    9.高阶装饰器(带参数的装饰器)

     1 def route(rule, **options):  # 从右往左执行 第一层实际上是传递参数
     2     def decorator(f):
     3         def inner(*args, **kwargs):
     4             print(options)
     5             # dic =
     6             print({**options})
     7             # print(**options)
     8             endpoint = options.pop("endpoint", f.__name__)  # 弹出字典里面的值
     9             print("被装饰的函数为:", endpoint)
    10             print(rule)
    11             res = f(*args, **kwargs)
    12             print("in decorator")
    13             print(id(f))
    14             return res
    15 
    16         return inner
    17 
    18     return decorator
    19 
    20 
    21 dic = {"name": "dgf", "age": 18}
    22 
    23 
    24 @route('/我是路由/', name="dgf")  # 这句话等同于 func=outer(func)
    25 def printIn(str):
    26     # print(id(printIn))
    27     print('h')
    28     return str
    29 
    30 
    31 ret = printIn("hello world")
    32 print(ret)
     1 import time
     2 
     3 
     4 def timmer_out(flag):
     5     def timmer(f):
     6         def inner(*args, **kwargs):
     7             if flag:
     8                 start = time.time()
     9                 ret = f(*args, **kwargs)
    10                 end = time.time()
    11                 print(end - start)
    12                 return ret
    13             else:
    14                 ret = f(*args, **kwargs)
    15                 return ret
    16 
    17         return inner
    18 
    19     return timmer
    20 
    21 
    22 @timmer_out(True)
    23 def func():
    24     time.sleep(0.1)
    25     print("我是func")
    26 
    27 
    28 func()
    29 """
    30 我是func
    31 0.10094308853149414
    32 """
    View Code

    再将参数改为FALSE

     1 import time
     2 
     3 
     4 def timmer_out(flag):
     5     def timmer(f):
     6         def inner(*args, **kwargs):
     7             if flag:
     8                 start = time.time()
     9                 ret = f(*args, **kwargs)
    10                 end = time.time()
    11                 print(end - start)
    12                 return ret
    13             else:
    14                 ret = f(*args, **kwargs)
    15                 return ret
    16 
    17         return inner
    18 
    19     return timmer
    20 
    21 
    22 @timmer_out(False)
    23 def func():
    24     time.sleep(0.1)
    25     print("我是func")
    26 
    27 
    28 func()
    29 """
    30 我是func
    31 """
    View Code

    这里实际上要分两步看这个问题

    10.多个装饰器装饰一个函数

     1 def func1(f):
     2     def inner(*args, **kwargs):
     3         print("fun1 start")
     4         func_ret = f()
     5         print("fun1 end")
     6         return func_ret
     7 
     8     return inner
     9 
    10 
    11 def func2(f):
    12     def inner(*args, **kwargs):
    13         print("fun2 start")
    14         func_ret = f()
    15         print("fun2 end")
    16         return func_ret
    17 
    18     return inner
    19 
    20 
    21 def func3(f):
    22     def inner(*args, **kwargs):
    23         print("fun3 start")
    24         func_ret = f()
    25         print("fun3 end")
    26         return func_ret
    27 
    28     return inner
    29 
    30 
    31 @func3
    32 @func2
    33 @func1
    34 def func():
    35     print("func")
    36 
    37 
    38 if __name__ == "__main__":
    39     func()
    40 
    41 """
    42 fun3 start
    43 fun2 start
    44 fun1 start
    45 func
    46 fun1 end
    47 fun2 end
    48 fun3 end
    49 
    50 """
    View Code
  • 相关阅读:
    POJ 3710 Christmas Game#经典图SG博弈
    POJ 2599 A funny game#树形SG(DFS实现)
    POJ 2425 A Chess Game#树形SG
    LeetCode Array Easy 122. Best Time to Buy and Sell Stock II
    LeetCode Array Easy121. Best Time to Buy and Sell Stock
    LeetCode Array Easy 119. Pascal's Triangle II
    LeetCode Array Easy 118. Pascal's Triangle
    LeetCode Array Easy 88. Merge Sorted Array
    ASP.NET MVC 学习笔记之 MVC + EF中的EO DTO ViewModel
    ASP.NET MVC 学习笔记之面向切面编程与过滤器
  • 原文地址:https://www.cnblogs.com/d9e84208/p/10598077.html
Copyright © 2011-2022 走看看