簡體   English   中英

為什么 Python 在打印回溯時從當前目錄讀取?

[英]Why does Python read from the current directory when printing a traceback?

$ echo "Your code is bad and you should feel bad" > "<stdin>"
$ python
Python 3.6.0 (default, Dec 28 2016, 19:53:26) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-11)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 2 + '2'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
    Your code is bad and you should feel bad
TypeError: unsupported operand type(s) for +: 'int' and 'str'

為什么 Python 會將字符串"<stdin>"與匹配該文件名的文件混淆? 如果遇到未處理的異常,我不希望 Python 嘗試從我的磁盤讀取任何文件。

您還可以使用"<string>"文件名獲取它:

$ echo "pining for the fjords" > "<string>"
$ python -c 'wat'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
    pining for the fjords
NameError: name 'wat' is not defined

有什么辦法可以防止這種行為,還是硬編碼到 REPL 中?

Python 不會跟蹤哪些源代碼對應於任何已編譯的字節碼。 在需要打印回溯之前,它甚至可能不會讀取該源代碼,例如,如果從.pyc文件加載模塊。

當 Python 需要打印回溯時,它會嘗試查找與所涉及的所有堆棧幀對應的源代碼。 您在堆棧跟蹤中看到的文件名和行號都是 Python 必須繼續的。 如果它正在使用traceback模塊,則代碼路徑將通過linecache排除以<>開頭和結尾的文件名的部分,但默認的sys.excepthook不會通過該路徑。

默認的sys.excepthook通過本機調用PyErr_Display ,最終使用_Py_DisplaySourceLine顯示單個源代碼行。 _Py_DisplaySourceLine無條件地嘗試在當前工作目錄中查找文件(出於某種原因 - 誤導優化?),然后調用_Py_FindSourceFile以在sys.path中搜索與該名稱匹配的文件,如果工作目錄沒有它。 通常,它不會找到<stdin><string>文件,並且當它找不到文件時它只會跳過打印源代碼,但如果找到一個,它會從該文件打印。

我最初認為你可以通過使用-I標志運行 Python 來防止這種情況,將其置於隔離模式。 隔離模式的影響之一是從sys.path刪除腳本的目錄。 實驗證明這並沒有改變事情,這就是當我意識到_Py_DisplaySourceLine嘗試工作目錄的時候。

通過在本機代碼路徑中排除<>文件名來解決這個問題是相當簡單的,就像linecache一樣。 無條件在當前目錄中搜索文件的代碼也應該更改。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM