簡體   English   中英

在一行中調試python單步執行(微步執行?)

[英]debugging python single stepping within a line (micro-stepping?)

據我所知,python調試器pdb一次只能一行。

Python是人們傾​​向於使用長單行表達式的語言之一。

像pdb這樣的調試器中是否有某種方式可以在一行代碼中“微步” 進行 就像在其中一樣,是否有一種方法可以在表達式的每個部分完成之后執行單步操作,然后將值傳遞給表達式的下一部分,並能夠檢查每個點返回的內容?

我意識到,如果可以編輯文件(並非總是可能或不實際),則可以通過插入換行符或添加中間值來拆分這樣的行,但並非總是可以編輯文件,尤其是當您走進圖書館。

首先,以我的經驗,人們不會在Python中編寫長的單行表達式…當然可以,但是PEP 8卻不鼓勵這樣做,而且您通常從中學到的教程,stdlib和其他示例代碼看起來也不像那樣。

但是,人們確實會編寫非常復雜的表達式。 特別是,他們使用諸如理解和迭代器之類的東西。

無論如何,這種事情的子表達式是什么,在某種程度上是模棱兩可的,因此尚不清楚進入它們的含義。

讓我們舉一個簡單的例子:

x = [i*2 for i in range(3)]

顯然, range(3)是一個子表達式。 但是還有什么呢? i*2是子表達式嗎? 還是三個?

在幕后,實際上是這樣的:

x = _hidden_func(range(3))

並且該隱藏函數(實際上名為類似<listcomp-123912576> ,而不是_hidden_func )是在編譯時直接從字節碼中構建的,並且未映射到任何實際的有效Python代碼。 大致是這樣的:

def _hidden_func(iterable):
    result = []
    iterator = iter(iterable)
    while True:
        try:
            i = next(iterator)
            result.append(i*2)
        except StopIteration:
            return result

…但是它使用快速的列表構建和next StopIteration字節碼,這些字節碼無法映射到您實際可以寫的任何東西。

因此,為了完全了解i*2 ,您需要進入一個沒有源代碼的功能,甚至不能即時將其反編譯為源代碼。

實際上, pdb已經可以做到這一點……但是它無法向您顯示任何有趣的東西。

顯然,您可以使用此代碼執行多種操作。 您可以選擇其中之一並編寫實現此目的的自定義代碼。 該可視化器顯示了一種可能性。

相同的可視化器將一個長而簡單的表達式(例如x = 2 * i**2 + 3 * i + 4 )作為一個步驟來對待,但是顯然,您可以通過例如遍歷字節碼並反編譯每個“有趣的”來處理此問題。 ”字節碼。

但是同樣,您必須決定什么才是“有趣的”,並編寫適當的代碼。 i**2可能感興趣,但是i呢? 您是否在關心是否要進行本地,閉包或全局查找,或者查找的內容,還是只想跳過它?

就像您說的那樣,沒有“微步”。 只有step

但是我經常用! 語句來執行一行的一部分。 要使用上面的示例:

>>> def foo(i):
...     return 2*i**2 + 3*i + 4
>>>
>>> import pdb
>>> pdb.runcall(foo, 5)
-> return 2*i**2 + 3*i + 4
(Pdb) !2*i**2
50
(Pdb) !3*i + 4
19

並且如果該行中有多個函數,但是我只想進入其中一個函數,那么我將使用debug輸入一個遞歸調試器:

>>> def foo(i):
...     return fn(i) + fn2(i) * fn3(i)
>>>
>>> import pdb
>>> pdb.runcall(foo, 5)
-> return fn(i) + fn2(i) * fn3(i)
(Pdb) debug fn3(i)
ENTERING RECURSIVE DEBUGGER
> <string>(1)<module>()
((Pdb))
# step through fn3 code...

有關更多信息! 和其他命令在這里

暫無
暫無

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

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