วิธีการใช้งานคำสั่งหลายบรรทัดภายในดีบักเกอร์ของ Python (PDB)


157

ดังนั้นฉันจึงเรียกใช้สคริปต์ Python ที่ฉันเรียกดีบักเกอร์ Python, PDB โดยการเขียน:

import ipdb; ipdb.set_trace()

(PDB เวอร์ชัน iPython แต่สำหรับเรื่องที่ฉันไม่คิดว่ามันสร้างความแตกต่างฉันใช้มันเพื่อผลสีเท่านั้น)

ตอนนี้เมื่อฉันไปที่ debugger ฉันต้องการที่จะดำเนินการคำสั่งหลายบรรทัดเช่นถ้าประโยคหรือสำหรับลูป แต่ทันทีที่ฉันพิมพ์

if condition:

และกดปุ่มย้อนกลับฉันได้รับข้อความแสดงข้อผิดพลาด *** SyntaxError: invalid syntax (<stdin>, line 1)

หนึ่งสามารถดำเนินการคำสั่งหลายบรรทัดภายใน PDB ได้อย่างไร ถ้าเป็นไปไม่ได้มีวิธีแก้ไขปัญหานี้ยังคงดำเนินการประโยคถ้าหรือห่วง?

คำตอบ:


265

คุณสามารถทำได้ในขณะที่อยู่ใน pdb เพื่อเปิดใช้งานเซสชัน Python แบบโต้ตอบชั่วคราวที่มีตัวแปรโลคัลทั้งหมดที่มี:

(pdb) !import code; code.interact(local=vars())
Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41) 
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> 

เมื่อเสร็จแล้วให้ใช้ Ctrl-D เพื่อกลับสู่พรอมต์ pdb ปกติ

เพียงแค่ไม่กด Ctrl-C นั่นจะเป็นการสิ้นสุดเซสชัน pdb ทั้งหมด


46
ดูเหมือนว่าสามารถทำได้โดยใช้interactคำสั่งpdb ( อย่างที่ฉันได้เรียนรู้จากข้อความตัวติดตามข้อผิดพลาดนี้ )
gerrit

3
ทำไมจึง!จำเป็นในimportคำสั่ง
Indradhanush Gupta

19
มันอาจไม่จำเป็น แต่ฉันมีนิสัยที่จะเติมคำสั่ง Python ทั้งหมดไว้ใน pdb ด้วย!เพื่อหลีกเลี่ยงอุบัติเหตุ เช่นc = 42ใน PDB จะยังคงcดำเนินการแทนการกำหนดให้กับตัวแปร
Marius Gedminas

8
@MariusGedmin เป็นสิ่งที่น่าผิดหวังที่สุดกับ PDB! คงจะดีถ้าพวกเขาคำสั่งจะต้องถูกนำหน้า ...
เอียนคลาร์ก

หมายเหตุ: Ctrl-D ดูเหมือนจะเป็นวิธีที่ถูกต้องinteractเช่นกัน แต่มันก็เล่นได้ไม่ดีกับ Spyder สำหรับฉัน
Josiah Yoder

69

ใน python3 ipdb(และpdb) มีคำสั่งที่เรียกว่าโต้ตอบ มันสามารถใช้ในการ:

เริ่มล่ามแบบโต้ตอบ (โดยใช้โมดูลโค้ด ) ซึ่งเนมสเปซส่วนกลางมีชื่อ (โกลบอลและโลคอล) ทั้งหมดที่พบในขอบเขตปัจจุบัน

หากต้องการใช้ให้ป้อนinteractที่พรอมต์ pdb เหนือสิ่งอื่นใดมันมีประโยชน์สำหรับการใช้โค้ดที่ครอบคลุมหลายบรรทัดและเพื่อหลีกเลี่ยงการทริกเกอร์คำสั่ง pdb อื่นโดยไม่ตั้งใจ


2
มันทำให้ฉัน "NameError: ชื่อ 'ปฏิสัมพันธ์' ไม่ได้กำหนดไว้" เมื่อทำอย่างนั้น
Jason

1
@jason เวอร์ชัน 3.2 หรือสูงกว่า
vaer-k

2
ที่อธิบาย ฉันอยู่ในหลาม 2.7
Jason

ระวังสิ่งนี้จริง ๆ แล้วโยนข้อผิดพลาดที่โต้ตอบไม่สามารถกำหนดและออกจากกระบวนการ
Camron_Godbout

1
ฉันคิดว่าการหลีกเลี่ยงinteractเป็นข้อเสนอแนะที่แรงเกินไป 90% นี่คือทั้งหมดที่ฉันต้องการและมันง่ายกว่ามากในการพิมพ์from IPython import embed; embed()
vaer-k

43

คำแนะนำของฉันคือการใช้การฝัง IPython

ipdb> from IPython import embed; embed()

2
หากคุณมีค่าไม่ได้กำหนดข้อผิดพลาดในรายการเข้าใจพยายามที่จะใช้จาก import embed; embed(user_ns=locals())IPython
fx-kirin

1
มันใช้งานได้ดีกว่าสำหรับฉันมากกว่าคำตอบที่ยอมรับ ตัวอย่างเช่น - อนุญาตให้แก้ไขแบบหลายบรรทัดได้อย่างเหมาะสมเช่นกลับไปสองสามบรรทัดและแก้ไขบางอย่างดังนั้นคุณไม่จำเป็นต้องเขียนนิพจน์หลายบรรทัดทั้งหมดอีกครั้งอีกครั้ง ... ฉันผ่านคนในพื้นที่เป็น @ fx-kirin ข้อเสนอแนะ
ZeDuS

33

ภายใน Python (2.7.1) interpreter หรือ debugger (import pdb) คุณสามารถรันคำสั่งแบบหลายบรรทัดด้วยไวยากรณ์ต่อไปนี้

for i in range(5): print("Hello"); print("World"); print(i)

หมายเหตุ: เมื่อฉันอยู่ในล่ามฉันต้องกดปุ่ม return สองครั้งก่อนที่โค้ดจะทำงาน อย่างไรก็ตามในตัวดีบั๊กฉันต้องตีกลับครั้งเดียวเท่านั้น


5
มันไม่อนุญาตให้ทำงานอะไรที่ลึกเกินกว่าระดับเดียว
Antony Hatchkins

7

มีกรณีพิเศษหากคุณต้องการคำสั่งสองสามคำสั่งเมื่อกดจุดพัก commandsจากนั้นก็มีคำสั่งดีบัก อนุญาตให้คุณป้อนคำสั่งหลายบรรทัดแล้วจบลำดับทั้งหมดด้วยendคำสำคัญ (pdb) help commandsมากขึ้นด้วย


2

ฉันไม่รู้ว่าคุณสามารถทำได้หรือไม่นั่นเป็นคุณสมบัติที่ยอดเยี่ยมสำหรับ ipdb คุณสามารถใช้ list comprehensions แน่นอนและดำเนินการนิพจน์แบบหลายบรรทัดอย่างเช่น:

if y == 3: print y; print y; print y;

คุณสามารถเขียนบางฟังก์ชั่นไว้ล่วงหน้าเพื่อทำสิ่งที่คุณต้องการซึ่งปกติจะใช้หลายบรรทัด

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.