Python IDLE reload(sys)後print無法正常執行命令的原因

通常大多數人執行reload(sys)這條語句其實僅僅是爲了能夠修改Python的默認字符集,也就是能夠調用sys.setdefaultencoding()。但是如果在IDLE中執行reload(sys),就會導致接下來無法正常執行任何命令。

起初遇到這個問題也是束手無策,後來無意間在stackoverflow上看到有人說到了這個問題。原來是因爲IDLE作爲一個GUI Shell環境,在啓動初始化過程中,會設置特定的標準輸入、標準輸出和標準錯誤輸出,使得輸入和輸出都在IDLE的GUI Shell中,可以在IDLE中通過如下方式查看:

>>> import sys  
>>> print sys.stdin  
<idlelib.PyShell.PseudoInputFile object at 0x00000000027AF2E8>  
>>> print sys.stdout  
<idlelib.PyShell.PseudoOutputFile object at 0x00000000027AF320>  
>>> print sys.stderr  
<idlelib.PyShell.PseudoOutputFile object at 0x00000000027AF358>  
>>>   

而如果手動執行了reload(sys)以後,sys模塊的這三個變量將會被重置,導致輸出無法顯示在IDLE。所以解決方案很簡單,只需要在reload之前把這三個變量都複製一份,reload之後再恢復回來就行了:

>>> stdi,stdo,stde=sys.stdin,sys.stdout,sys.stderr  
>>> reload(sys)  
>>> sys.stdin,sys.stdout,sys.stderr=stdi,stdo,stde  
>>> print sys.stdout  
<idlelib.PyShell.PseudoOutputFile object at 0x00000000027AF320>  
>>>   

細心的人可能會想到,reload(sys)之後,如果標準輸入、標準輸出和標準錯誤輸出都不起作用了,那麼relaod(sys)後面那一句sys.stdin,sys.stdout,sys.stderr=stdi,stdo,stde怎麼能夠執行呢?所以其實reload(sys)之後、恢復之前,標準輸入還是可以正常工作的,可以通過如下代碼來檢驗:

>>> reload(sys)  
>>> sys.stdout=stdo  
>>> print sys.stdin  
<open file '<stdin>', mode 'r' at 0x0000000001CAB030>  
>>> print sys.stdout  
<idlelib.PyShell.PseudoOutputFile object at 0x00000000027AF320>  
>>> print sys.stderr  
<open file '<stderr>', mode 'w' at 0x0000000001CAB150>  
>>>   

所以問題就解決了,但是必須要強調:

千萬不要輕易使用reload(sys),除非你完全清除這麼做帶來的結果!僅僅爲了能夠重新設定Python的默認編碼就執行reload(sys)更是非常不明智的行爲!

Python的設計者故意在Python初始化完成以後刪除sys模塊裏面的setdefaultencoding()方法,就是爲了不讓在運行時隨意更改Python默認編碼,以免出現一些未知的問題。事實上,關於編碼問題,完全有別的更可靠的方法解決。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章