2 回答
TA貢獻(xiàn)1811條經(jīng)驗(yàn) 獲得超6個(gè)贊
我認(rèn)為,使用堆棧跟蹤,您正在尋找錯(cuò)誤的地方。當(dāng)您print_stack從一個(gè)地方調(diào)用時(shí),該方法僅在來自 dunder 方法時(shí)執(zhí)行,該方法很好地包含在輸出中。
我試過這段代碼來驗(yàn)證:
import sys
import traceback
from enum import Enum
class TestEnum(Enum):
"""Test enum."""
A = "A"
class MyIter:
def __init__(self):
self.i = 0
def __next__(self):
self.i += 1
if self.i <= 1:
traceback.print_stack(file=sys.stdout)
return TestEnum.A
raise StopIteration
def __iter__(self):
return self
def main():
for enum_member in MyIter():
print(f"enum member = {enum_member}.")
if __name__ == "__main__":
main()
堆棧跟蹤的最后一行打印為
File "/home/lydia/playground/demo.py", line 21, in __next__
traceback.print_stack(file=sys.stdout)
在您的原始代碼中,您在所有 dunder 方法都已返回時(shí)獲取堆棧跟蹤。因此,它們已從堆棧中刪除。
所以我認(rèn)為,你想看看調(diào)用圖。我知道 IntelliJ / PyCharm 至少在付費(fèi)版本中可以很好地做到這一點(diǎn)。
您可能還想嘗試其他工具。你覺得 pycallgraph怎么樣?
更新:
Python 使得轉(zhuǎn)儲(chǔ)所有函數(shù)調(diào)用的簡(jiǎn)單列表實(shí)際上非常容易。
基本上你需要做的就是
import sys
sys.setprofile(tracefunc)
tracefunc根據(jù)您的需要編寫。在這個(gè) SO 問題上找到一個(gè)工作示例:How do I print functions as they are called
警告:我需要從外部 shell 啟動(dòng)腳本。通過在我的 IDE 中使用播放按鈕啟動(dòng)它意味著腳本永遠(yuǎn)不會(huì)終止,而是編寫越來越多的行。我認(rèn)為它與我的 IDE 完成的內(nèi)部分析相沖突。
官方文檔sys.setprofile:https ://docs.python.org/3/library/sys.html#sys.setprofile
還有一個(gè)關(guān)于 Python 跟蹤的隨機(jī)教程:https ://pymotw.com/2/sys/tracing.html
但是請(qǐng)注意,根據(jù)我的經(jīng)驗(yàn),您可以對(duì)“誰在給誰打電話?”這個(gè)問題獲得最好的見解?;蛘摺斑@個(gè)價(jià)值是從哪里來的?” 通過使用普通的調(diào)試器。
TA貢獻(xiàn)1801條經(jīng)驗(yàn) 獲得超8個(gè)贊
我還對(duì)該主題進(jìn)行了一些研究,因?yàn)锧LydiaVanDyke 的答案中的信息促進(jìn)了更好的搜索。
打印整個(gè)調(diào)用堆棧
正如@LydiaVanDyke 指出的那樣,IDE 調(diào)試器是一個(gè)非常好的方法。我使用 PyCharm,發(fā)現(xiàn)這是我最喜歡的解決方案,因?yàn)榭梢裕?/p>
遵循函數(shù)調(diào)用 + 代碼中的確切行號(hào)
閱讀調(diào)用周圍的代碼,更好地理解打字
跳過不想調(diào)查的電話
另一種方法是 Python 的標(biāo)準(zhǔn)庫的trace. 它提供了命令行和可嵌入的方法來打印整個(gè)調(diào)用堆棧。
還有一個(gè)是 Python 的內(nèi)置調(diào)試器模塊,pdb. 這(通過調(diào)用pdb.set_trace())真的改變了我的游戲。
Profiler 輸出的可視化
gprof2dot是另一個(gè)有用的分析器可視化工具。
查找源代碼
由于我的 IDE 的存根文件 (PyCharm),我的其他問題之一實(shí)際上并沒有看到真正的源代碼。
如何檢索Python函數(shù)的源代碼詳述了實(shí)際打印源代碼的兩種方法
使用所有這些工具,您會(huì)感到非常有能力!
添加回答
舉報(bào)
