從一開始使用群益API時,就經常收到這個錯誤輸出。
Error in sys.excepthook:
Original exception was:
不以為意,因為運行不會受到任何影響。
關於這個錯誤,用GOOGLE搜尋會找到一篇文章,有做探討。
確實是直指出錯誤問題來源,但是並沒有解釋到底為什麼會出錯。
前幾天著手多進程,因此更瞭解當中的運作模式,這篇會更詳細講看法與解法。
comtypes.client.GetEvents(),是可以把COM event傳到對應接收函式。
根據官方文件 COM events,comtypes.client.GetEvents() 會收到一個連接物件 ,只要保持這個物件,就能保持狀態。
群益API範例沒有寫很多,後來看確實都有意義在的。
當登入報價之後,若是只有使用 time.sleep(),是會收不到回傳資料。
於是使用 pythoncom.PumpWaitingMessages(),好讓那些訊息有進到到主線程的時間。
訊息跟主線程並不在同一條線程上,因此可想有個子線程專門接收資料,到時候在送到對應的接收函式。
comtypes.client.GetEvents()的回傳值,就相當於一個這樣功能的子線程。
重新回到 Error in sys.excepthook 錯誤上,從網路上可以很容易查到解釋,就是主線程關掉了,但子線程卻還在運行。
這個物件的有無,對應著子線程運行有無,這可以解釋探討錯誤該文章的十八格狀態。
為什麼函式內用 comtypes.client.GetEvents() 就不會報錯,而在全域用就會報錯?函式結束時,函式內部變數也就被刪除,所以變數指定透過 comtypes.client.GetEvents() 得到的連接物件也就被刪除,連接子線程跟著中止。
在全域使用,在主線程結束時,自然是不會刪去這個連接物件。
要刪去這個連接物件,只需要使用 del 就能刪除了,是相當簡單的。
導致錯誤的關鍵點,就只是有沒有在主線程結束前刪掉這個連接物件。
其實不論在哪個域或類別中使用,也只需要在主線程結束之前,刪掉這個物件,或從類別中刪除這個屬性,就不會報錯了。