Detailed explanation of two very practical Python decorators
- 2021-12-13 08:49:39
- OfStack
1. Timeout function
This function is to be able to give any possible hang live function to add timeout function, this function in the preparation of external API call, web crawler, database query time is particularly useful
The code for the timeout decorator is as follows:
import signal,functools # The following two libraries will be used
class TimeoutError(Exception): pass # Definition 1 A Exception Throw after timeout
def timeout(seconds, error_message = 'Function call timed out'):
def decorated(func):
def _handle_timeout(signum, frame):
raise TimeoutError(error_message)
def wrapper(*args, **kwargs):
signal.signal(signal.SIGALRM, _handle_timeout)
signal.alarm(seconds)
try:
result = func(*args, **kwargs)
finally:
signal.alarm(0)
return result
return functools.wraps(func)(wrapper)
return decorated
Use:
@timeout(5) # Define the following slowfunc Function if the 5s Forced throw if you don't return inside TimeoutError Exception End
def slowfunc(sleep_time):
import time
time.sleep(sleep_time) # This function is hibernation sleep_time Seconds
slowfunc(3) #sleep 3 Second, return normally No anomalies
slowfunc(10) # Be terminated
# # Output
---------------------------------------------------------------------------
TimeoutError Traceback (most recent call last)
2. Trace function
Sometimes, for demonstration purposes or debugging purposes, we need to print out the running sequence and calling logic of each step when the program runs. Similar to the bash-x debugging function when writing bash, and then the Python interpreter does not have built-in useful functions at this time, so we will "do it ourselves and have plenty of food and clothing".
The code for the Trace decorator is as follows:
'''
No one answers the problems encountered in study? Xiaobian created 1 A Python Learning and communication group: 725638078
Looking for like-minded friends and helping each other , There are also good video learning tutorials and PDF E-books!
'''
import sys,os,linecache
def trace(f):
def globaltrace(frame, why, arg):
if why == "call": return localtrace
return None
def localtrace(frame, why, arg):
if why == "line":
# record the file name and line number of every trace
filename = frame.f_code.co_filename
lineno = frame.f_lineno
bname = os.path.basename(filename)
print("{}({}): {}".format( bname,
lineno,
linecache.getline(filename, lineno).strip('\r\n')),)
return localtrace
def _f(*args, **kwds):
sys.settrace(globaltrace)
result = f(*args, **kwds)
sys.settrace(None)
return result
return _f
Use:
@trace
def xxx():
print (1)
print (22)
print (333)
xxx() # Call
# # Output
< ipython-input-4-da50741ac84e > (3): Output of print 1 # @ trace
1
< ipython-input-4-da50741ac84e > (4): Output of print 22 # @ trace
22
< ipython-input-4-da50741ac84e > (5): Output of print 333 # @ trace
333
Summarize
This article is here, I hope to give you help, but also hope that you can pay more attention to this site more content!