News from this site

 Rental advertising space, please contact the webmaster if you need cooperation


+focus
focused

classification  

no classification

tag  

no tag

date  

no datas

python装饰器详解

posted on 2023-05-03 20:56     read(489)     comment(0)     like(13)     collect(1)


The decorator         in python generally takes the form of syntactic sugar, which is a grammatical format. For example: @classmethod, @staticmethod, @property, @xxx.setter, @wraps(), @func_name, etc. are all decorators in python.

        Decorator, the decorated object is a function or method. The functions of various decorators are the same: to change the function and nature of the decorated function or method.

        The following mainly explains the two decorators @wraps(), @func_name, and class decorators.

Table of contents

1. The official definition of the decorator

Second, add a decorator to a function

1. General writing

2. Standard grammatical sugar writing

Second, add multiple decorators to a function

2.1 Add two decorators to a function

2.2 Execution order when a function has two decorators

3. Typical writing method with parameter decorator

Fourth, @wraps() syntax sugar (understand)

Five, class decorator

1. Class decorator without parameters

2. Class decorator with parameters


1. The official definition of the decorator

        A decorator is essentially a Python function (actually a closure), which allows other functions to add additional functions without any code changes. The return value of the decorator is also a function object. Decorators are used in the following scenarios, such as: inserting logs, performance testing, transaction processing, caching, permission verification and other scenarios.

Second, add a decorator to a function

1. General writing

  1. # 为函数添加一个统计运行时长的功能
  2. import time
  3. def how_much_time(func):
  4. def inner():
  5. t_start = time.time()
  6. func()
  7. t_end = time.time()
  8. print("一共花费了{0}秒时间".format(t_end - t_start, ))
  9. return inner
  10. # 将增加的新功能代码以及被装饰函数运行代码func()一同打包返回,返回的是一个内部函数,这个被返回的函数就是装饰器
  11. def sleep_5s():
  12. time.sleep(5)
  13. print("%d秒结束了" % (5,))
  14. def sleep_6s():
  15. time.sleep(6)
  16. print("%d秒结束了" % (6,))
  17. sleep_5s = how_much_time(sleep_5s)
  18. # 因为sleep_5s函数的功能就是睡5秒钟,虽然增加了统计运行时间的功能,但是他本身功能没变(还是睡5秒钟),所以仍然用原来函数名接收增加功能了的自己
  19. sleep_6s = how_much_time(sleep_6s)
  20. t1 = threading.Thread(target=sleep_5s)
  21. t2 = threading.Thread(target=sleep_6s)
  22. t1.start()
  23. t2.start()
  24. # 5秒结束了
  25. # 一共花费了5.014161109924316秒时间
  26. # 6秒结束了
  27. # 一共花费了6.011810302734375秒时间

2. Standard grammatical sugar writing

  1. # 为函数添加一个统计运行时长的功能
  2. import time
  3. import threading
  4. def how_much_time(func):
  5. def inner():
  6. t_start = time.time()
  7. func()
  8. t_end = time.time()
  9. print("一共花费了{0}秒时间".format(t_end - t_start, ))
  10. return inner
  11. @how_much_time
  12. # @how_much_time等价于sleep_5s = how_much_time(sleep_5s)
  13. def sleep_5s():
  14. time.sleep(5)
  15. print("%d秒结束了" % (5,))
  16. @how_much_time
  17. def sleep_6s():
  18. time.sleep(6)
  19. print("%d秒结束了" % (6,))
  20. t1 = threading.Thread(target=sleep_5s)
  21. t2 = threading.Thread(target=sleep_6s)
  22. t1.start()
  23. t2.start()

Second, add multiple decorators to a function

        Here is an example of adding two decorators.

2.1 Add two decorators to a function

  1. # 为函数添加一个统计运行时长的功能以及日志记录功能
  2. import time
  3. import threading
  4. def how_much_time(func):
  5. print("how_much_time函数开始了")
  6. def inner():
  7. t_start = time.time()
  8. func()
  9. t_end = time.time()
  10. print("一共花费了{0}秒时间".format(t_end - t_start, ))
  11. return inner
  12. def mylog(func):
  13. print("mylog函数开始了")
  14. def inner_1():
  15. print("start")
  16. func()
  17. print("end")
  18. return inner_1
  19. @mylog
  20. @how_much_time
  21. # 等价于mylog(how_much_time(sleep_5s))
  22. def sleep_5s():
  23. time.sleep(5)
  24. print("%d秒结束了" % (5,))
  25. if __name__ == '__main__':
  26. sleep_5s()
  27. #how_much_time函数开始了
  28. #mylog函数开始了
  29. #start
  30. #5秒结束了
  31. #一共花费了5.012601613998413秒时间
  32. #end

2.2 Execution order when a function has two decorators

3. Typical writing method with parameter decorator

Fourth, @wraps() syntax sugar (understand)

        Because the decorator is essentially a function, a modified function, it is two different function objects from the original undecorated function.

        Therefore, this decorator loses some attributes of the original function object, such as: __name__, __doc__ and other attributes. These properties can be preserved using wraps syntactic sugar.

Five, class decorator

        The main idea of ​​writing a class decorator is to return a function object with new functions added, but this function object is an instance object of a class. Since the decorator is a callable object, the __call__ method must be implemented in the class, so that various instances generated by the class can be run by adding ().

1. Class decorator without parameters

  1. import time
  2. class Decorator:
  3. def __init__(self, func):
  4. self.func = func
  5. def defer_time(self):
  6. time.sleep(5)
  7. print("延时结束了")
  8. def __call__(self, *args, **kwargs):
  9. self.defer_time()
  10. self.func()
  11. @Decorator
  12. def f1():
  13. print("延时之后我才开始执行")
  14. f1()

2. Class decorator with parameters

  1. import time
  2. class Decorator:
  3. def __init__(self, func):
  4. self.func = func
  5. def defer_time(self,time_sec):
  6. time.sleep(time_sec)
  7. print(f"{time_sec}s延时结束了")
  8. def __call__(self, time):
  9. self.defer_time(time)
  10. self.func()
  11. @Decorator
  12. def f1():
  13. print("延时之后我才开始执行")
  14. f1(5)



Category of website: technical article > Blog

Author:python98k

link:http://www.pythonblackhole.com/blog/article/255/9fbe565f5e0621870dbf/

source:python black hole net

Please indicate the source for any form of reprinting. If any infringement is discovered, it will be held legally responsible.

13 0
collect article
collected

Comment content: (supports up to 255 characters)