Python 開發模式

在 3.7 版被加入.

Python 開發模式引入了額外的 runtime 檢查,預設啟用這些檢查的成本太高。如果程式碼正確,它不應比預設值更詳細;僅當偵測到問題時才會發出新警告。

可以使用-Xdev 命令列選項或將PYTHONDEVMODE 環境變數設為 1 來啟用它。

另請參閱Python 除錯建置

Python 開發模式的影響

啟用 Python 開發模式類似以下指令,但具有如下所述的附加效果:

PYTHONMALLOC=debugPYTHONASYNCIODEBUG=1python-Wdefault-Xfaulthandler

Python 開發模式的效果:

Python 開發模式預設不會啟用tracemalloc 模組,因為(效能和記憶體的)開銷太大。啟用tracemalloc 模組可提供有關某些錯誤來源的附加資訊。例如ResourceWarning 記錄了分配資源之處的回溯、緩衝區溢位錯誤記錄了分配記憶體區塊的回溯。

Python 開發模式不會防止-O 命令列選項刪除assert 陳述式,也不會防止將__debug__ 設定為False

Python 開發模式只能在 Python 啟動時啟用。它的值可以從sys.flags.dev_mode 讀取。

在 3.8 版的變更:io.IOBase 解構函式現在會記錄close() 例外。

在 3.9 版的變更:現在會為字串編碼和解碼操作檢查encodingerrors 引數。

ResourceWarning 範例

計算命令列中指定的文字檔案列數的腳本範例:

importsysdefmain():fp=open(sys.argv[1])nlines=len(fp.readlines())print(nlines)# The file is closed implicitlyif__name__=="__main__":main()

該腳本不會明確關閉檔案。預設情況下,Python 不會發出任何警告。使用 README.txt 的範例,該檔案有 269 列:

$pythonscript.pyREADME.txt269

啟用 Python 開發模式會顯示ResourceWarning 警告:

$python-Xdevscript.pyREADME.txt269script.py:10: ResourceWarning: unclosed file <_io.TextIOWrapper name='README.rst' mode='r' encoding='UTF-8'>  main()ResourceWarning: Enable tracemalloc to get the object allocation traceback

此外,啟用tracemalloc 會顯示檔案被開啟的那一列:

$python-Xdev-Xtracemalloc=5script.pyREADME.rst269script.py:10: ResourceWarning: unclosed file <_io.TextIOWrapper name='README.rst' mode='r' encoding='UTF-8'>  main()Object allocated at (most recent call last):  File "script.py", lineno 10    main()  File "script.py", lineno 4    fp = open(sys.argv[1])

修復方法是明確關閉該檔案。以下是使用情境管理器的範例:

defmain():# Close the file explicitly when exiting the with blockwithopen(sys.argv[1])asfp:nlines=len(fp.readlines())print(nlines)

不明確關閉資源可能會使資源開啟的時間比預期的長得多;它可能會在退出 Python 時導致嚴重問題。在 CPython 中很糟糕,但在 PyPy 中更糟。明確關閉資源使應用程式更具確定性和可靠性。

檔案描述器的錯誤範例

顯示自身第一列的腳本:

importosdefmain():fp=open(__file__)firstline=fp.readline()print(firstline.rstrip())os.close(fp.fileno())# The file is closed implicitlymain()

預設情況下,Python 不會發出任何警告:

$pythonscript.pyimport os

Python 開發模式在最終化 (finalize) 檔案物件時顯示ResourceWarning 並記錄 "Bad file descriptor" 錯誤:

$python-Xdevscript.pyimport osscript.py:10: ResourceWarning: unclosed file <_io.TextIOWrapper name='script.py' mode='r' encoding='UTF-8'>  main()ResourceWarning: Enable tracemalloc to get the object allocation tracebackException ignored in: <_io.TextIOWrapper name='script.py' mode='r' encoding='UTF-8'>Traceback (most recent call last):  File "script.py", line 10, in <module>    main()OSError: [Errno 9] Bad file descriptor

os.close(fp.fileno()) 會關閉檔案描述器。當檔案物件最終化函式 (finalizer) 嘗試再次關閉檔案描述器時,它會失敗並出現Badfiledescriptor 錯誤。檔案描述器只能關閉一次。在最壞的情況下,將它關閉兩次可能會導致崩潰 (crash)(相關範例請參閱bpo-18748)。

修復方法是刪除os.close(fp.fileno()) 那列,或使用closefd=False 開啟檔案。