简体   繁体   English

捕获由try-block内的函数引发的自定义异常

[英]Catch custom Exception that is raised by a function inside the try-block

I've been trying to catch an exception that should be caused by clicking a hotkey, unfortunately adding a hotkey requires to add a function that should be called when said hotkey is pressed. 我一直在尝试捕获应该由单击热键引起的异常,不幸的是,添加热键需要添加一个在按下热键时应该调用的函数。

Now I know that exceptions will only be caught if they're raised inside the try-catch block, but this doesn't seem to work. 现在我知道只有在try-catch块中引发异常才会被捕获,但这似乎不起作用。

class resetException(Exception): pass

try:
    def resetRun(event):
        raise resetException

    Env.addHotkey(resetKey, 0, resetRun)

    while True:
        [...]
except resetException:
    popup("reset")

The exception is raised, but it seems like it isn't raised inside the try-block? 引发异常,但似乎它没有在try-block中引发? If I just raise the resetException without the function, this works perfectly fine. 如果我只是在没有函数的情况下引发resetException ,那么这非常正常。

Exception in thread "Thread-8" Traceback (most recent call last):
  File "Sikuli\sikulix.jar\Lib\sikuli\Env.py", line 13, in hotkeyPressed
  File "Sikuli\Test.sikuli\Test.py", line 339, in resetRun
    raise resetException
__main__.resetException

Is there any solution to this? 这有什么解决方案吗?

Thanks in advance! 提前致谢!

The problem is that you're out of the main thread's context. 问题是你不在主线程的上下文中。 This is a multi-threaded environment which is hinted by you binding keys to callbacks. 这是一个多线程环境,通过将键绑定到回调来暗示。

There is probably an eventloop with a thread (or threads) waiting to handle your key callbacks once a user presses a key. 一旦用户按下某个键,可能会有一个等待处理键回调的线程(或多个线程)的eventloop。

What you need to do is put the try-catch inside the resetRun so that the thread actually executing the code (which is calling your callback) can handle the exception. 您需要做的是将try-catch放在resetRun以便实际执行代码的线程(调用您的回调)可以处理异常。

You could create a wrapper like this: 您可以创建一个这样的包装器:

def with_try_catch(f):
    def wrapped():
        try:
            f()
        catch YourException:
            # handle exception
    return wrapped

Now bind like this: 现在像这样绑定:

Env.addHotkey(resetKey, 0, with_try_catch(resetRun))

That's because the exception inside your function doesn't raised at run-time . 那是因为函数内部的异常不会在运行时引发。 The fact is that a try-except expression will catch the exceptions in run-time, for example: 事实是try-except表达式将在运行时捕获异常,例如:

>>> try:
...     def a():
...        raise ValueError
...     a()
... except ValueError:
...     print('The exception is caught')
... 
The exception caught

And in this case it seems that you are just instantiating an object or smth. 在这种情况下,您似乎只是实例化一个对象或smth。 (your function is not executed at run-time) (您的函数不会在运行时执行)

Env.addHotkey(resetKey, 0, resetRun)

Which means that the exceptions will raise after compile time (when you use that function), in this case, when you push the button. 这意味着在编译时(使用该函数时)之后会出现异常,在这种情况下,当您按下按钮时。

So if you want to handle the exception inside the function you need to catch them inside the function. 因此,如果您想在函数内部处理异常,则需要在函数内捕获它们。

I am no expert, but it seems to me that the problem is your def resetRun(event) bit. 我不是专家,但在我看来,问题是你的def resetRun(event)位。 The try...except instruction set cannot dig into a function definition. try...except指令集无法深入到函数定义中。 What happens if you create resetRun(event) outside of try...except ? 如果你在try...except创建resetRun(event)会发生什么? Does it work then? 那会有用吗?

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

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