使用装饰器捕获错误

0 投票
1 回答
655 浏览
提问于 2025-05-01 07:02

我正在尝试用一个装饰器来捕捉线程中的错误:

class cc:
    def catch_exceptions(job_func):
        @functools.wraps(job_func)
        def wrapper(*args, **kwargs):
            try:
                job_func(*args, **kwargs)
            except:
                import traceback
                print(traceback.format_exc())
            return wrapper

    @catch_exceptions
    def job(self, name, command):
        #print("I'm running on thread %s" % threading.current_thread())
        os.system(command)

    def run_threaded(self, job_func, name, command):
        job_thread = threading.Thread(target=job_func, args=(name, command,) )
        job_thread.start()

但是我遇到了这个问题:

File "/usr/local/lib/python2.7/dist-packages/schedule/__init__.py", line 320, in do
self.job_func = functools.partial(job_func, *args, **kwargs)
TypeError: the first argument must be callable

我该如何让 job_func 可以被调用呢?

暂无标签

1 个回答

5

你的装饰器缩进有问题;把 return wrapper 这一行的缩进去掉。

现在这样写的话,你的装饰器返回的是 None,所以 cc.job 被设置成了 None

修正后的版本应该是:

def catch_exceptions(job_func):
    @functools.wraps(job_func)
    def wrapper(*args, **kwargs):
        try:
            job_func(*args, **kwargs)
        except:
            import traceback
            print(traceback.format_exc())
    return wrapper

你可能不想在这里使用完全空白的 except;这样的话,你会捕捉到键盘中断和系统退出的异常。虽然在一个线程中这没什么大不了的(如果这些异常没有被捕捉,它们不会影响到主线程),但 通常来说,你至少应该使用 except Exception:

撰写回答