2010-10-26 102 views
4

我試圖調試與Windows DLL的一個ctypes包裝問題,當我通過交互式shell中運行測試已經注意到差異(Python或IPython中),當我運行腳本是非交互式的。Python的差異

我想知道是否有任何解釋我在這裏看到的差異?

具體而言,當我交互運行一個簡單的測試,一個DLL調用將掛起,再也不回來,那裏的準確運行的腳本相同的代碼不會出現此問題。

要什麼我的意思是更明確,想象你有下面的代碼

from foobar import bar, foo 
bar(foo(1,2,3)) 

放在一個文件時,說「myfoo.py」,並通過「蟒蛇myfoo.py」 excecuted,上面的代碼按預期執行。但是,如果你在上面輸入到一個Python/IPython的外殼,該代碼具有不同的行爲(在我的情況下,掛起調用ctypes.WinDLL功能時)

一些額外的細節:

我使用的是相同的口譯員和兩種情況下的相同PYTHONPATH。 封裝的DLL是Canon EDSDKv2.9,一個用於遠程控制攝像頭的SDK。 它總是掛在DLL中,而不是在Python代碼中。

初始化時,我EDSDK包裝啓動一個線程其run方法是這樣的:

def run(self): 
    sys.coinit_flags = 0 #use multithreaded mode 
    from pythoncom import PumpWaitingMessages 
    #^^ done here so this thread is correctly initialised 
    error(EDSDK.EdsInitializeSDK()) 
    self.EDSDK_initialised = True 
    while self.active: 
     PumpWaitingMessages() 
     sleep(self.msg_sleep_time) 
    error(EDSDK.EdsTerminateSDK()) 

此線程的目的基本上是初始化SDK,泵的消息,並允許其他線程調用包裝方法。

注:此工作過,既交互式和非交互式,在以前的版本中EDSDK。我目前的問題只發生在最新版本的EDSDK中。

我懷疑這可能是與線程(因此片斷),但不能在網上找到的任何信息備份我的懷疑。

所以,交互式和非交互式運行時蟒是任何人都知道的任何差異?可能與windows線程有關?任何幫助,甚至是野蠻的猜測,在這一點上都會受到讚賞,因爲我完全被絆倒了! :)

回答

1

Python交互式解釋器不是線程安全的。因此,如果您嘗試發送阻止命令,則整個解釋器將掛起。

this article,爲什麼發生這種情況(文藝青年最愛的是,空閒和線程不混合)。至於如何解決這個問題,請使用控制檯而不是IDLE GUI。或者,您可以使用腳本。

1

在異步或併發操作(例如多線程,多處理)的環境中需要記住這一點。對於交互式運行Python的所有意圖和目的,您沒有主循環。即使__name__設置爲__main__,但在此處分配或執行的任何操作都可能不可用。特別是多處理的情況,以及在某些情況下多線程,其中對象的狀態可能不會在進程/線程之間共享。

這種行爲在最壞情況下可能會令人困惑,最糟糕的情況是危險的。在調試時進入的一個好習慣是始終命名你的線程,並使用Python的logging模塊來配對,以跟蹤幕後發生的事情。