no classification
no tag
no datas
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
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)
1. Class decorator without parameters
2. Class decorator with parameters
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.
- # 为函数添加一个统计运行时长的功能
- import time
-
- def how_much_time(func):
- def inner():
- t_start = time.time()
- func()
- t_end = time.time()
- print("一共花费了{0}秒时间".format(t_end - t_start, ))
- return inner
- # 将增加的新功能代码以及被装饰函数运行代码func()一同打包返回,返回的是一个内部函数,这个被返回的函数就是装饰器
-
- def sleep_5s():
- time.sleep(5)
- print("%d秒结束了" % (5,))
-
- def sleep_6s():
- time.sleep(6)
- print("%d秒结束了" % (6,))
-
- sleep_5s = how_much_time(sleep_5s)
- # 因为sleep_5s函数的功能就是睡5秒钟,虽然增加了统计运行时间的功能,但是他本身功能没变(还是睡5秒钟),所以仍然用原来函数名接收增加功能了的自己
- sleep_6s = how_much_time(sleep_6s)
-
- t1 = threading.Thread(target=sleep_5s)
- t2 = threading.Thread(target=sleep_6s)
- t1.start()
- t2.start()
- # 5秒结束了
- # 一共花费了5.014161109924316秒时间
- # 6秒结束了
- # 一共花费了6.011810302734375秒时间
- # 为函数添加一个统计运行时长的功能
- import time
- import threading
-
- def how_much_time(func):
- def inner():
- t_start = time.time()
- func()
- t_end = time.time()
- print("一共花费了{0}秒时间".format(t_end - t_start, ))
-
- return inner
-
-
- @how_much_time
- # @how_much_time等价于sleep_5s = how_much_time(sleep_5s)
- def sleep_5s():
- time.sleep(5)
- print("%d秒结束了" % (5,))
-
- @how_much_time
- def sleep_6s():
- time.sleep(6)
- print("%d秒结束了" % (6,))
-
- t1 = threading.Thread(target=sleep_5s)
- t2 = threading.Thread(target=sleep_6s)
- t1.start()
- t2.start()
-
Here is an example of adding two decorators.
- # 为函数添加一个统计运行时长的功能以及日志记录功能
- import time
- import threading
-
- def how_much_time(func):
- print("how_much_time函数开始了")
- def inner():
- t_start = time.time()
- func()
- t_end = time.time()
- print("一共花费了{0}秒时间".format(t_end - t_start, ))
- return inner
-
- def mylog(func):
- print("mylog函数开始了")
- def inner_1():
- print("start")
- func()
- print("end")
- return inner_1
-
- @mylog
- @how_much_time
- # 等价于mylog(how_much_time(sleep_5s))
- def sleep_5s():
- time.sleep(5)
- print("%d秒结束了" % (5,))
-
- if __name__ == '__main__':
- sleep_5s()
- #how_much_time函数开始了
- #mylog函数开始了
- #start
- #5秒结束了
- #一共花费了5.012601613998413秒时间
- #end
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.
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 ().
- import time
-
-
- class Decorator:
- def __init__(self, func):
- self.func = func
-
- def defer_time(self):
- time.sleep(5)
- print("延时结束了")
-
- def __call__(self, *args, **kwargs):
- self.defer_time()
- self.func()
-
-
- @Decorator
- def f1():
- print("延时之后我才开始执行")
-
-
- f1()
- import time
-
- class Decorator:
- def __init__(self, func):
- self.func = func
-
- def defer_time(self,time_sec):
- time.sleep(time_sec)
- print(f"{time_sec}s延时结束了")
-
- def __call__(self, time):
- self.defer_time(time)
- self.func()
-
- @Decorator
- def f1():
- print("延时之后我才开始执行")
-
- f1(5)
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.
name:
Comment content: (supports up to 255 characters)
Copyright © 2018-2021 python black hole network All Rights Reserved All rights reserved, and all rights reserved.京ICP备18063182号-7
For complaints and reports, and advertising cooperation, please contact vgs_info@163.com or QQ3083709327
Disclaimer: All articles on the website are uploaded by users and are only for readers' learning and communication use, and commercial use is prohibited. If the article involves pornography, reactionary, infringement and other illegal information, please report it to us and we will delete it immediately after verification!