简体   繁体   English

如何在Python中分析异常处理?

[英]How to profile exception handling in Python?

Is there a way to find out how many exceptions are thrown (and caught) and maybe how much time exception handling took? 有没有办法找出抛出(和捕获)的异常数量,以及异常处理花了多少时间?

I'm using pyparsing (slightly modified) which relies heavily on exceptions and I want to find out (or at least estimate) if it would be worth the effort to rewrite it to work without exceptions. 我正在使用pyparsing (略微修改),它严重依赖于异常,我想找出(或至少估计)是否值得努力将其重写为无异常工作。

Raising and catching of exceptions is widely scattered over the module so I'm searching a way which doesn't need to modify each try-except-block 提升和捕获异常广泛分散在模块上,因此我正在寻找一种不需要修改每个try-except-block的方法

Whenever you want to profile code, using a contextmanager is probably a good idea 每当您想要分析代码时,使用上下文管理器可能是个好主意

import time
from contextlib import contextmanager

# global
NUMBER_OF_EXCEPTIONS = 0

# define the timer
class Timer(object):
    def __init__(self):
        self.t1 = time.time()
    def stop(self):
        self.t2 = time.time()
        self.elapsed = self.t2 - self.t1

# define the profiler
@contextmanager
def profiler():
    t = Timer()
    yield t
    t.stop()
    print("elapsed: ", t.elapsed)

# use the profiler!
with profiler():
    try:
        1/0
    except ZeroDivisionError:
        # handle exception
        NUMBER_OF_EXCEPTIONS += 1
        time.sleep(1.1)

# and use it again!
with profiler():
    try:
        1/2
    except ZeroDivisionError:
        # handle exception
        NUMBER_OF_EXCEPTIONS += 1
        time.sleep(1.1)

print("Total handled exceptions: ", NUMBER_OF_EXCEPTIONS)

The output should be something like this: 输出应该是这样的:

elapsed:  1.10120511055
elapsed:  4.05311584473e-06
Total handled exceptions:  1

Now if you want to get really fancy, you can write context managers for handling your exceptions too ( source ). 现在,如果你想变得非常花哨,你也可以编写上下文管理器来处理异常( 源代码 )。 This technique can lead to very clean code: 这种技术可以导致非常干净的代码:

NUMBER_OF_EXCEPTIONS = 0

@contextmanager
def handle_zero_division_error():
    try:
        yield
    except ZeroDivisionError as err:
        global NUMBER_OF_EXCEPTIONS
        NUMBER_OF_EXCEPTIONS += 1
        time.sleep(1.1)

with profiler():
    with handle_zero_division_error():
        1/0

with profiler():
    with handle_zero_division_error():
        1/0

# you can even write it like this
with profiler(), handle_zero_division_error():
    1/2

print("Total handled exceptions: ", NUMBER_OF_EXCEPTIONS)

And the output: 并输出:

elapsed:  1.10123705864
elapsed:  1.10085892677
elapsed:  1.90734863281e-05
Total handled exceptions:  2

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM