1. ホーム
  2. スクリプト・コラム
  3. パイソン

Pythonの非常に便利な2つのデコレーターを解説

2022-01-02 13:06:05

1. タイムアウト関数

この関数の目的は、ハングアップする可能性のある関数にタイムアウト機能を追加することであり、特に外部APIコール、Webクローラ、データベースクエリを記述する際に有用である

タイムアウト・デコレーターのコードは次のとおりです。 :

import signal,functools #The following two libraries will be used 
class TimeoutError(Exception): pass #Define an Exception to be thrown after a 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

使用しています。

@timeout(5) #Finalize the following slowfunc function to force a TimeoutError Exception if it does not return within 5s 
def slowfunc(sleep_time):
  import time
  time.sleep(sleep_time) # this function is to sleep sleep_time seconds 
slowfunc(3) #sleep 3 seconds, normal return no exceptions
slowfunc(10) #is terminated 


## 出力
---------------------------------------------------------------------------
TimeoutError トレースバック (最新のコールバック)

2. トレース機能

デモやデバッグのために、プログラム実行時に各ステップのシーケンスや呼び出しロジックをプリントアウトする必要がある場合があります。これはbashを書くときのbash -xのデバッグ機能に似ていますが、Pythonインタプリタにはこの便利な機能は組み込まれていないので、自分で"することになります。

Traceデコレータのコードは以下の通りです。

'''
No one to answer your questions in learning? I created a Python learning exchange group: 725638078
Looking for like-minded partners to help each other, the group also has 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

使用しています。

@trace
def xxx():
  print (1)
  print (22)
  print (333)
xxx() # call 

## 出力
/{br
1

22

333

概要

この記事はこれで終わりです。この記事があなたの助けになることを願っていますし、BinaryDevelopの他のコンテンツにもっと注目していただけることを願っています