2016-07-17 68 views
1

我一直在試圖捕獲應該由於單擊熱鍵而引起的異常,不幸的是,添加一個熱鍵需要添加一個函數,熱鍵被按下。Catch自定義的異常是由try-block內部的函數引發的

現在我知道只有在try-catch塊內部引發異常時纔會捕獲異常,但這似乎不起作用。

class resetException(Exception): pass 

try: 
    def resetRun(event): 
     raise resetException 

    Env.addHotkey(resetKey, 0, resetRun) 

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

引發異常,但它似乎不是在try塊內引發的?如果我只是在沒有該功能的情況下提升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 

有沒有解決方法?

在此先感謝!

+1

這是多線程? (看起來像你的綁定鍵,所以我猜你有一個事件循環活動) –

+0

從try..catch塊取出異常函數 –

+0

爲什麼用'try/catch'封裝'def'?將它移動到'def'中。 –

回答

-1

我不是專家,但在我看來,這個問題是你的def resetRun(event)位。 try...except指令集無法挖掘到函數定義。如果您在try...except之外創建resetRun(事件),會發生什麼情況?那它有用嗎?

+0

不幸的是,這並沒有改變任何東西。因爲'raise'必須發生在try/catch塊內部,我認爲這不會起作用。 – klayveR

0

這是因爲您的函數內的異常不會在運行時上引發。事實是,一個try-except expression將趕上在運行時的異常,例如:

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

在這種情況下,似乎你只是實例化一個對象或等(問題是,你的函數沒有按」牛逼執行在運行時)

Env.addHotkey(resetKey, 0, resetRun) 

這意味着例外將編譯時間後擡起(當你使用該功能),在這種情況下,當你按下按鈕。

所以,如果你想處理函數內的異常,你需要在函數內部捕獲它們。

1

問題是,你不在主線程的上下文中。這是一個多線程環境,通過將鍵綁定到回調來暗示。

當用戶按下某個鍵時,可能會有一個線程(或多個線程)等待處理您的鍵回調的eventloop。

你需要做的就是將try-catch放在resetRun的內部,以便實際執行代碼(調用你的回調函數)的線程可以處理異常。

您可以創建這樣的包裝:

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

現在結合這樣的:

Env.addHotkey(resetKey, 0, with_try_catch(resetRun)) 
相關問題