การดีบักแบบทีละขั้นตอนด้วย IPython


170

จากสิ่งที่ฉันได้อ่านมีสองวิธีในการดีบักโค้ดใน Python:

  • ด้วยการดีบักแบบดั้งเดิมเช่นหรือpdb ipdbสิ่งนี้รองรับคำสั่งเช่นcfor continue, nfor step-over, sfor step-intoฯลฯ ) แต่คุณไม่มีสิทธิ์เข้าถึงโดยตรงไปยัง IPython shell ซึ่งมีประโยชน์อย่างมากสำหรับการตรวจสอบวัตถุ

  • ใช้ IPythonโดยฝังเปลือก IPython ในรหัสของคุณ คุณสามารถทำได้from ipython import embedจากนั้นใช้embed()รหัสของคุณ เมื่อโปรแกรม / สคริปต์ของคุณพบembed()คำสั่งคุณจะถูกดร็อปเข้าสู่เชลล์ IPython สิ่งนี้จะช่วยให้การตรวจสอบวัตถุและการทดสอบรหัส Python เต็มรูปแบบโดยใช้สินค้า IPython ทั้งหมด อย่างไรก็ตามเมื่อใช้งานembed()คุณจะไม่สามารถทีละขั้นตอนในรหัสอีกต่อไปด้วยแป้นพิมพ์ลัดที่มีประโยชน์

มีวิธีใดบ้างที่จะรวมสิ่งที่ดีที่สุดของทั้งสองโลกเข้าด้วยกัน? กล่าวคือ

  1. สามารถ ทีละขั้นตอนผ่านรหัสของคุณด้วยแป้นพิมพ์ลัด pdb / ipdb ที่มีประโยชน์
  2. ในขั้นตอนดังกล่าวใด ๆ (เช่นเกี่ยวกับคำสั่งที่กำหนด) มีการเข้าถึงที่เต็มเปี่ยมIPython เปลือก

การดีบัก IPython เหมือนกับใน MATLAB:

ตัวอย่างของประเภทของ "การปรับปรุงการแก้จุดบกพร่อง" นี้สามารถพบได้ใน MATLAB ที่ผู้ใช้มักจะมีการเข้าถึงแบบเต็มไปยังเครื่องยนต์ MATLAB / เปลือกและเธอยังสามารถขั้นตอนโดยขั้นตอนผ่านรหัสของเธอกำหนดจุดพักตามเงื่อนไขอื่น ๆ จาก สิ่งที่ฉันได้พูดคุยกับผู้ใช้คนอื่น ๆ นี่คือคุณสมบัติการแก้ไขข้อบกพร่องที่ผู้คนคิดถึงมากที่สุดเมื่อย้ายจาก MATLAB ไปเป็น IPython

การดีบัก IPython ใน Emacs และเครื่องมือแก้ไขอื่น ๆ :

ฉันไม่ต้องการตั้งคำถามให้เฉพาะเจาะจงเกินไป แต่ฉันทำงานเป็นส่วนใหญ่ใน Emacs ดังนั้นฉันจึงสงสัยว่ามีวิธีใดที่จะนำฟังก์ชันนี้มาใช้ นึกคิด , Emacs (หรือแก้ไข) จะช่วยให้โปรแกรมเมอร์ชุดจุดพักที่ใดก็ได้บนรหัสและสื่อสารกับล่ามหรือดีบักที่จะมีมันหยุดในสถานที่ที่คุณเลือกและนำไป IPython ล่ามเต็มรูปแบบในสถานที่นั้น


pdb มี!คำสั่งที่รันคำสั่ง python ใด ๆ ที่เบรกพอยต์
Dmitry Galchinsky

5
ฉันกำลังมองหาดีบักหลามคล้ายกับ Matlab ด้วย! ตัวอย่างเช่นฉันทำต้นแบบจำนวนมากในเปลือกงูหลาม ตัวแปรทั้งหมดจะถูกบันทึกด้วยเชลล์ ตอนนี้ฉันพบปัญหา ฉันหวังว่าจะดีบักโค้ดขนาดเล็กหนึ่งชิ้นโดยใช้ตัวแปรที่คำนวณด้วยเชลล์ อย่างไรก็ตามดีบักเกอร์ใหม่ไม่สามารถเข้าถึงตัวแปรเก่าได้ มันไม่สะดวกในการทำต้นแบบ
user1914692

1
สำหรับผู้ใช้ Emacs RealGUD มีส่วนต่อประสานที่ดีอย่างเหลือเชื่อ
Clément

1
ขอบคุณ @ Clémentฉันติดตาม repo มาเมื่อเดือนที่แล้วและฉันรู้สึกตื่นเต้นมากเกี่ยวกับโครงการ :) ฉันยังไม่ได้ลอง แต่เมื่อฉันทำ (หรือถ้าคุณทำ) รู้สึกอิสระที่จะเขียนคำตอบที่นี่ซึ่งอาจ แสดงวิธีการบรรลุสิ่งที่ร้องขอ สำหรับผู้อื่นสำหรับการอ้างอิง URL คือgithub.com/rocky/emacs-dbgr
Amelio Vazquez-Reina

@ Clémentนอกจากนี้หากคุณมีประสบการณ์กับ RealGUD & ipdb ฉันลองใช้มันตามที่อธิบายไว้ที่นี่github.com/rocky/emacs-dbgr/issues/96โดยไม่มีโชค
Amelio Vazquez-Reina

คำตอบ:


61

คุณสามารถใช้ IPython ของมายากล%pdb เพียงแค่โทร%pdbใน IPython ipdbและเมื่อเกิดข้อผิดพลาดที่คุณกำลังลดลงโดยอัตโนมัติ ในขณะที่คุณไม่ได้ก้าวไปทันทีคุณก็เข้าipdbมา

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

%pdbเป็นเวทมนตร์สาย เรียกว่าเป็น%pdb on, %pdb 1, หรือ%pdb off %pdb 0ถ้าเรียกโดยไม่มีข้อโต้แย้งมันทำงานเป็นสลับ


6
^ นี่คือคำตอบที่แท้จริง
Cesar

มีบางอย่างที่คล้ายกันที่ pdb มี IPython เหมือนกับการทำงานโดยไม่ต้องอยู่ใน IPython ในตอนแรกหรือไม่?
ลูคัส

4
นอกจากนี้คุณยังสามารถเริ่มโปรแกรมด้วยipython --pdb file.py -- argsและจะถูกปล่อยไปที่ ipdb โดยมีข้อยกเว้น อาจจะเพิ่มมูลค่าให้กับคำตอบ
เซบาสเตียน

110

แล้ว ipdb.set_trace () ล่ะ? ในรหัสของคุณ:

import ipdb; ipdb.set_trace()

update : ตอนนี้ใน Python 3.7 เราสามารถเขียนbreakpoint()ได้ มันใช้งานได้เหมือนกัน แต่ก็เป็นไปตามPYTHONBREAKPOINTตัวแปรสภาพแวดล้อม คุณลักษณะนี้มาจากPEPนี้

สิ่งนี้ช่วยให้สามารถตรวจสอบรหัสของคุณได้อย่างเต็มที่และคุณสามารถเข้าถึงคำสั่งเช่นc(ดำเนินการต่อ), n(ดำเนินการบรรทัดถัดไป), s(เข้าสู่ขั้นตอนวิธีการทันที) และอื่น ๆ

ดูrepo ipdbและรายการของคำสั่ง IPythonเรียกว่าตอนนี้ (แก้ไข: ส่วนหนึ่งของ) Jupyter


ps: โปรดทราบว่าคำสั่ง ipdb มีความสำคัญมากกว่ารหัสหลาม ดังนั้นเพื่อที่จะเขียนคุณจะต้องlist(foo)print list(foo)

นอกจากนี้ถ้าคุณชอบ ipython พรอมต์ (emacs และโหมดที่เป็นกลุ่มประวัติศาสตร์ความสำเร็จ, ... ) มันเป็นเรื่องง่ายที่จะได้รับเช่นเดียวกันสำหรับโครงการของคุณเพราะมันขึ้นอยู่กับงูหลามเครื่องมือพร้อมท์


10
นี่คือวิธีที่จะทำ
j08lue

คำตอบของฉันตอนนี้รวมถึงวิธีการใช้ipdbใน Emacs ที่ใช้RealGUDและisend-modeเพื่อทำสิ่งที่ OP ต้องการ
Amelio Vazquez-Reina

1
Jupyter ไม่ได้แทน IPython แต่สำหรับ IPython Notebook สมุดบันทึก Jupyter ใช้เคอร์เนลในพื้นหลัง สำหรับโน้ตบุ๊ก Python เคอร์เนลมักจะเป็นเคอร์เนล IPython โครงการ IPythonยังคงต่อไป
FA

1
breakpoint()เป็นสิ่งที่ยอดเยี่ยม ใน PyCharm มันจะส่งคุณไปยังดีบักเกอร์ PyCharm นอกจากนี้ยังเป็นวิธีที่รวดเร็วในการเข้าสู่ดีบักเกอร์ PyCharm จากฟังก์ชั่นที่วางลงในคอนโซล
Richard Möhn

40

(อัปเดตเมื่อวันที่ 28 พฤษภาคม 2016) การใช้ RealGUD ใน Emacs

สำหรับทุกคนใน Emacs เธรดนี้แสดงวิธีการทำทุกอย่างที่อธิบายไว้ใน OP (และอื่น ๆ ) โดยใช้

  1. ดีบักเกอร์สำคัญใหม่ใน Emacs ที่เรียกว่าRealGUDซึ่งสามารถทำงานกับดีบักเกอร์ใด ๆ (รวมถึงipdb)
  2. isend-modeแพคเกจ Emacs

การรวมกันของสองแพ็คเกจนี้มีประสิทธิภาพสูงมากและทำให้สามารถสร้างพฤติกรรมที่อธิบายไว้ใน OP และทำสิ่งต่างๆได้มากขึ้น

ข้อมูลเพิ่มเติมเกี่ยวกับบทความ wikiของ RealGUD สำหรับ ipdb


คำตอบเดิม:

หลังจากลองใช้วิธีต่างๆมากมายในการดีบัก Python รวมถึงทุกอย่างที่กล่าวถึงในเธรดนี้หนึ่งในวิธีที่ฉันต้องการในการดีบัก Python กับ IPython คือการใช้เชลล์ฝังตัว

การกำหนดเปลือก IPython แบบฝังที่กำหนดเอง:

เพิ่มสคริปต์ต่อไปนี้ในของคุณPYTHONPATHเพื่อให้วิธีการipsh()ใช้งานได้

import inspect

# First import the embed function
from IPython.terminal.embed import InteractiveShellEmbed
from IPython.config.loader import Config

# Configure the prompt so that I know I am in a nested (embedded) shell
cfg = Config()
prompt_config = cfg.PromptManager
prompt_config.in_template = 'N.In <\\#>: '
prompt_config.in2_template = '   .\\D.: '
prompt_config.out_template = 'N.Out<\\#>: '

# Messages displayed when I drop into and exit the shell.
banner_msg = ("\n**Nested Interpreter:\n"
"Hit Ctrl-D to exit interpreter and continue program.\n"
"Note that if you use %kill_embedded, you can fully deactivate\n"
"This embedded instance so it will never turn on again")   
exit_msg = '**Leaving Nested interpreter'

# Wrap it in a function that gives me more context:
def ipsh():
    ipshell = InteractiveShellEmbed(config=cfg, banner1=banner_msg, exit_msg=exit_msg)

    frame = inspect.currentframe().f_back
    msg   = 'Stopped at {0.f_code.co_filename} at line {0.f_lineno}'.format(frame)

    # Go back one level! 
    # This is needed because the call to ipshell is inside the function ipsh()
    ipshell(msg,stack_depth=2)

จากนั้นเมื่อใดก็ตามที่ฉันต้องการตรวจแก้จุดบกพร่องบางอย่างในรหัสของฉันฉันวางipsh()ขวาที่ตำแหน่งที่ฉันต้องทำการตรวจสอบวัตถุ ฯลฯ ตัวอย่างเช่นฉันต้องการตรวจแก้จุดบกพร่องmy_functionด้านล่าง

ใช้มัน:

def my_function(b):
  a = b
  ipsh() # <- This will embed a full-fledged IPython interpreter
  a = 4

และจากนั้นฉันเรียกใช้my_function(2)หนึ่งในวิธีต่อไปนี้:

  1. ไม่ว่าโดยการรันโปรแกรม Python ที่เรียกใช้ฟังก์ชันนี้จาก Unix shell
  2. หรือโดยการเรียกใช้โดยตรงจาก IPython

ipsh()โดยไม่คำนึงถึงวิธีการที่ฉันเรียกมันล่ามหยุดที่บรรทัดที่ระบุว่า เมื่อเสร็จแล้วคุณสามารถทำได้Ctrl-Dและ Python จะกลับมาทำงานต่อ (พร้อมกับการปรับปรุงตัวแปรที่คุณทำ) โปรดทราบว่าถ้าคุณเรียกใช้รหัสจาก IPython ปกติ IPython shell (กรณีที่ 2 ด้านบน), IPython shell ใหม่จะซ้อนอยู่ภายในรหัสที่คุณเรียกใช้ซึ่งดีมาก แต่ก็ควรระวัง เมื่อล่ามหยุดที่ตำแหน่งของipshฉันฉันสามารถตรวจสอบค่าของa(ซึ่ง2), ดูฟังก์ชั่นและวัตถุที่มีการกำหนด ฯลฯ

ปัญหา:

วิธีการแก้ปัญหาข้างต้นสามารถใช้เพื่อให้ Python หยุดทุกที่ที่คุณต้องการในรหัสของคุณจากนั้นนำคุณไปสู่ล่าม IPython น่าเสียดายที่มันไม่ยอมให้คุณเพิ่มหรือลบเบรกพอยต์เมื่อคุณเรียกใช้สคริปต์ซึ่งน่าผิดหวังอย่างมาก ในความเห็นของฉันนี่เป็นเพียงสิ่งเดียวเท่านั้นสิ่งที่ทำให้ IPython กลายเป็นเครื่องมือดีบั๊กสำหรับ Python

สิ่งที่ดีที่สุดที่คุณสามารถทำได้ในตอนนี้:

วิธีแก้ปัญหาคือการวางipsh()นิรนัยที่ตำแหน่งต่าง ๆ ที่คุณต้องการให้ Python interpreter เปิดใช้เชลล์ IPython (เช่น a breakpoint) จากนั้นคุณสามารถ "ข้าม" ระหว่าง "เบรกพอยต์" ที่กำหนดไว้ล่วงหน้าแบบกำหนดรหัสล่วงหน้าด้วยCtrl-Dซึ่งจะออกจากเชลล์ IPython ที่ฝังอยู่ในปัจจุบันและหยุดอีกครั้งเมื่อใดก็ตามที่ล่ามกดการโทรครั้งต่อไปipsh()เปลือกและหยุดอีกครั้งเมื่อใดก็ตามที่ล่ามฮิตโทรไปเพื่อ

หากคุณไปที่เส้นทางนี้วิธีหนึ่งในการออกจาก "โหมดแก้ไขจุดบกพร่อง" และละเว้นจุดพักที่ตามมาทั้งหมดคือการใช้ipshell.dummy_mode = Trueซึ่งจะทำให้ Python ไม่สนใจอินสแตนซ์ของipshellวัตถุที่เราสร้างขึ้นด้านบน


2
โปรดอัปเดตสิ่งนี้เมื่อใดก็ตามที่คุณพบทางออกที่ดียิ่งขึ้น แต่นี่ดูดีมาก ฉันจะใช้มัน
ฟานี

1
คุณกำหนด / นำเข้า cfg, banner_msg, exit_msg และตรวจสอบที่ไหน
Gordon Bean

1
ดูเหมือนว่าจะใช้งานได้ดีสำหรับฉัน: github.com/kdodia/snippets/blob/master/ipsh.py
karan.dodia

1
ฉันต้องการเพิ่มimport inspectก่อนใช้งาน ดูเหมือนว่าการกำหนดค่าบรรทัดคำสั่งจะใช้งานไม่ได้สำหรับฉัน
ปาสกาล

7
ทำไมไม่ใช้เพียงimport ipdb; ipdb.set_trace()? บางทีฉันอาจจะพลาดบางอย่าง แต่ฉันไม่เห็นความได้เปรียบของวิธีการที่ซับซ้อนกว่านี้ของคุณ
ชำระเงิน

19

คุณสามารถเริ่มเซสชัน IPython จากpudbและกลับไปที่เซสชันการดีบักตามที่คุณต้องการ

BTW, ipdb กำลังใช้ IPython ที่อยู่เบื้องหลังและคุณสามารถใช้ฟังก์ชันการทำงานของ IPython เช่นการเติมคำสั่ง TAB และคำสั่งเวทมนต์ (อันที่เริ่มต้นด้วย%) หากคุณตกลงกับ ipdb คุณสามารถเริ่มต้นได้จาก IPython โดยใช้คำสั่งเช่น%runและ%debugและipdb session นั้นดีกว่า IPython ธรรมดาอย่างใดอย่างหนึ่งในแง่ที่คุณสามารถขึ้นและลงใน stack trace และอื่น ๆ สิ่งที่ขาดหายไปใน ipdb สำหรับ "การตรวจสอบวัตถุ"?

นอกจากนี้ python.el ที่มาพร้อมกับ Emacs> = 24.3 มีการสนับสนุน ipdb ที่ดี


1
ขอบคุณ tkf ฉันเป็นแฟนตัวยงของแพ็คเกจ Emacs-Jedi ของคุณ เมื่อคุณพูดว่า Emacs 24.3 ได้รับการสนับสนุนที่ดีสำหรับ ipdb คุณจะอธิบายอย่างละเอียดไหม? ฉันมักจะเริ่ม IPython ในM-x ansi-termบัฟเฟอร์ที่แยกต่างหากจากนั้นฉันใช้โหมด isendเพื่อผูกบัฟเฟอร์แหล่งที่มาของฉันกับบัฟเฟอร์ IPython เพื่อให้ฉันสามารถส่งรหัสไปยังล่าม IPython ด้วยแป้นพิมพ์ลัดที่ส่ง%pasteเวทมนตร์ไปยังบัฟเฟอร์ IPython โดยอัตโนมัติ นี่ทำให้ฉันสามารถทดสอบภูมิภาคใน IPython ได้อย่างรวดเร็ว ฉันมักจะเรียกใช้โปรแกรมของฉันจากเปลือก IPython นี้ด้วยrunและใช้embed()เพื่อหยุด
Amelio Vazquez-Reina

3
ตัวอย่างเช่นเมื่อคุณก้าวผ่านโค้ดซอร์สโค้ดจะเปิดขึ้นในบัฟเฟอร์อีกลูกศรชี้ไปที่จุดดำเนินการปัจจุบัน คุณมีคำสั่ง send-region เหมือนที่คุณทำกับโหมด isend
tkf

ขอบคุณ @tkf ฉันจะเริ่มipdbเซสชั่นการดีบักโดยใช้python.elและมีสิ่งsend-regionอื่น ๆเช่นเปลือกที่สอดคล้องกันได้อย่างไร โดยทั่วไปแล้วฉันจะหาข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้ได้จากที่ไหน
Amelio Vazquez-Reina

การใช้งานผมหรือ%run %debugฉันเดาว่าimport ipdb; ipdb.set_trace()ทำงานเหมือนกัน ฉันไม่คิดว่าคุณสามารถส่งหลายบรรทัดไปยัง ipdb นั่นคือข้อ จำกัด ของ ipdb แต่อาจใช้%pasteกลอุบายได้ คุณอาจต้องการส่งคำขอคุณสมบัติไปที่ IPython dev
tkf

13

ดูเหมือนว่าวิธีการในคำตอบของ @ gaborous เลิกใช้แล้วจะเลิก

แนวทางใหม่น่าจะเป็น:

from IPython.core import debugger
debug = debugger.Pdb().set_trace

def buggy_method():
    debug()

สิ่งนี้อนุญาตให้คุณใช้ipdbคำสั่งภายใน ipython shell ในขณะที่ทำการดีบั๊กหรือไม่?
alpha_989

6

คำนำหน้า "!" สัญลักษณ์คำสั่งที่คุณพิมพ์ใน pdb ดูเหมือนว่าจะมีผลเช่นเดียวกับการทำอะไรบางอย่างในเปลือก IPython วิธีนี้ใช้สำหรับการเข้าถึงวิธีใช้สำหรับฟังก์ชั่นบางอย่างหรือแม้กระทั่งชื่อตัวแปร บางทีนี่อาจช่วยคุณได้บ้าง ตัวอย่างเช่น,

ipdb> help(numpy.transpose)
*** No help on (numpy.transpose)

แต่! help (numpy.transpose) จะให้หน้าความช่วยเหลือที่คาดหวังไว้ใน numpy.transpose ในทำนองเดียวกันสำหรับชื่อตัวแปรสมมติว่าคุณมีตัวแปร l โดยพิมพ์ "l" ใน pdb แสดงรหัส แต่! l พิมพ์ค่า l


2
นี่คือ pdb gotcha ที่น่ารังเกียจและควรค่าแก่การรู้
Wilfred Hughes

4

คุณลองใช้เคล็ดลับนี้หรือไม่?

หรือยังดีกว่าใช้ ipython และโทร:

from IPython.Debugger import Tracer; debug_here = Tracer()

จากนั้นคุณสามารถใช้

debug_here()

ทุกครั้งที่คุณต้องการตั้งค่าเบรกพอยต์


4

คุณสามารถเริ่มIPython จากภายใน ipdb !

ชักนำให้ipdbดีบักเกอร์1 :

import idpb; ipdb.set_trace()

ป้อน IPython จากภายในในipdb>คอนโซล2 :

from IPython import embed; embed()

กลับไปที่ipdb>คอนโซลจากภายในIPython:

exit

หากคุณโชคดีพอที่จะใช้ Emacs คุณสามารถทำสิ่งต่าง ๆ ได้สะดวกยิ่งขึ้น!

M-x shellนี้ต้องใช้ ใช้yasnippetและbmกำหนดตัวอย่างต่อไปนี้ สิ่งนี้จะแทนที่ข้อความipdbในเครื่องมือแก้ไขด้วยset-traceบรรทัด หลังจากใส่ข้อมูลโค้ดบรรทัดจะถูกเน้นเพื่อให้สังเกตได้ง่ายและนำทาง ใช้M-x bm-nextเพื่อนำทาง

# -*- mode: snippet -*-
# name: ipdb
# key: ipdb
# expand-env: ((yas-after-exit-snippet-hook #'bm-toggle))
# --
import ipdb; ipdb.set_trace()

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

2คุณสามารถพิมพ์ด้วยตัวเองโดยการนำเข้าไฟล์IPython ของคุณ.pdbrc :

try:
    from IPython import embed
except:
    pass

สิ่งนี้ช่วยให้คุณสามารถโทรembed()จากภายในipdb(แน่นอนเมื่อติดตั้ง IPython เท่านั้น)


3

ทางเลือกหนึ่งคือการใช้ IDE เช่นSpyderซึ่งจะช่วยให้คุณสามารถโต้ตอบกับโค้ดของคุณในขณะที่ทำการดีบัก (โดยใช้คอนโซล IPython อันที่จริง) ในความเป็นจริง Spyder นั้นเหมือน MATLAB มากซึ่งฉันคิดว่าเป็นความตั้งใจ ซึ่งรวมถึงตัวตรวจสอบตัวแปรการแก้ไขตัวแปรการเข้าถึงเอกสารในตัว ฯลฯ


3

คำตอบที่ถูกต้องง่ายเย็นสบายและแน่นอนคือใช้% run macro ที่มีแฟล็ก -d

In [4]: run -d myscript.py
NOTE: Enter 'c' at the ipdb>  prompt to continue execution.        
> /cygdrive/c/Users/mycodefolder/myscript.py(4)<module>()
      2                                                            
      3                        
----> 4 a=1                                            
      5 b=2

ควรสูงกว่านี้ หากฉันต้องการแทรกบรรทัดลงในรหัสของฉัน (ภายในโมดูล) ฉันต้องรีสตาร์ท IPython เพื่อโหลดโมดูลอีกครั้ง ด้วยสิ่งนี้ฉันทำได้เพียง%save /tmp/foo.py x-yรหัสที่ฉันต้องการเรียกใช้และตรวจแก้จุดบกพร่องจากนั้น%run -d /tmp/foo.pyตั้งจุดพักได้ทุกที่ คำตอบที่ดี!
Romeo Valentin


2

Pyzo IDE มีความสามารถใกล้เคียงกับ OP ถาม คุณไม่ต้องเริ่มในโหมดแก้ไขข้อบกพร่อง เช่นเดียวกับ MATLAB คำสั่งจะถูกดำเนินการในเชลล์ เมื่อคุณตั้งค่าจุดหยุดในบางบรรทัดซอร์สโค้ด IDE จะหยุดการทำงานที่นั่นและคุณสามารถดีบักและออกคำสั่ง IPython ปกติได้เช่นกัน

ดูเหมือนว่าขั้นตอนในจะทำงานได้ไม่ดี (เช่นหยุดในบรรทัดเดียวแล้วก้าวเข้าสู่ฟังก์ชั่นอื่น) เว้นแต่คุณจะตั้งจุดพักใหม่

ยังมาจาก MATLAB นี่เป็นทางออกที่ดีที่สุดที่ฉันเคยพบ


2

จาก python 3.2 คุณมีinteractคำสั่งซึ่งให้สิทธิ์การเข้าถึงพื้นที่คำสั่ง python / ipython แบบเต็ม


1

การเรียกใช้จาก IPython-shell และชุดเบรกพอยต์ของ Emacs ผ่าน pdb.set_trace () ควรใช้งานได้

ตรวจสอบกับ python-mode.el, Mx ipython RET เป็นต้น


1

การพัฒนารหัสใหม่

การดีบักภายใน IPython

  1. ใช้การทำงานของเซลล์ Jupyter / IPython เพื่อเพิ่มความเร็วในการทดสอบซ้ำ
  2. ใช้การแก้จุดบกพร่อง %% สำหรับขั้นตอนต่างๆ

ตัวอย่างเซลล์:

%%debug
...: for n in range(4):
...:    n>2

การดีบักรหัสที่มีอยู่

IPython ภายในการดีบัก

  1. การดีบักการทดสอบหน่วยที่ใช้งานไม่ได้: pytest ... --pdbcls=IPython.terminal.debugger:TerminalPdb --pdb
  2. แก้จุดบกพร่องด้านนอกของกรณีทดสอบ: breakpoint(), python -m ipdbฯลฯ
  3. IPython.embed () สำหรับการทำงานของ IPython เต็มรูปแบบตามที่จำเป็นในขณะที่อยู่ในดีบักเกอร์

ความคิดเกี่ยวกับงูหลาม

ฉันเห็นด้วยกับ OP ว่าหลายสิ่งหลายอย่างที่ MATLAB ทำได้ดี Python ยังไม่มีและควรจะเป็นเพราะทุกอย่างในภาษานั้นต้องการความเร็วในการพัฒนามากกว่าความเร็วในการผลิต บางทีสักวันหนึ่งฉันจะมีส่วนร่วมมากกว่าการแก้ไขข้อบกพร่องเล็กน้อยใน CPython

https://github.com/ipython/ipython/commit/f042f3fea7560afcb518a1940daa46a72fbcfa68

ดูเพิ่มเติมเป็นไปได้ไหมที่จะรันคำสั่งใน IPython ด้วยการดีบั๊ก?

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