IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    两个实用的 python 装饰器: timeout超时控制 和 trace单步追踪

    admin发表于 2017-05-24 10:43:25
    love 0

    timeout超时控制

    通过设置时钟信号给函数添加超时终端功能, 不适用于通过 os.system() 调用外部程序的情形.

    import signal
    import functools
     
    class TimeoutError(Exception):
      pass
     
    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(3)
      def slowfunc(sleep_time):
        import time
        time.sleep(sleep_time)
     
      if '__main__' == __name__:
        slowfunc(1)
        print 'ok'
     
        try:
          slowfunc(5)
        except TimeoutError:
          print 'timeout'

    trace单步追踪

    提供类似 bash -x 调试功能, 打印执行的每一行代码.

    import os
    import sys
    import linecache
     
    def trace(f):
      def localtrace(frame, why, arg):
        if 'line' == why:
          # record the file name and line number of every trace 
          filepath = frame.f_code.co_filename
          lineno = frame.f_lineno
          print '{filepath}({lineno}): {line}'.format(
            filepath=filepath,
            lineno=lineno,
            line=linecache.getline(filepath, lineno).strip('\r\n'))
     
        return localtrace
     
      def globaltrace(frame, why, arg):
        if 'call' == why:
          return localtrace
        return None
     
      def _f(*args, **kwards):
        sys.settrace(globaltrace)
        result = f(*args, **kwards)
        sys.settrace(None)
        return result
     
      return _f
     
    @trace
    def xxx():
      print 1
     
      result = ''
      for i in ['1', '2', '3']:
        if i == '3':
          result += i
     
      print result
     
    if '__main__' == __name__:
      xxx()

    输出示例:

    python2 ./test/trace.py
    ./test/trace.py(34):   print 1
    1
    ./test/trace.py(36):   result = ''
    ./test/trace.py(37):   for i in ['1', '2', '3']:
    ./test/trace.py(38):     if i == '3':
    ./test/trace.py(37):   for i in ['1', '2', '3']:
    ./test/trace.py(38):     if i == '3':
    ./test/trace.py(37):   for i in ['1', '2', '3']:
    ./test/trace.py(38):     if i == '3':
    ./test/trace.py(39):       result += i
    ./test/trace.py(37):   for i in ['1', '2', '3']:
    ./test/trace.py(41):   print result
    3

    原文地址:http://www.logevery.com/python/python_two_decorate_timeout_and_trace.html



沪ICP备19023445号-2号
友情链接