Bagaimana cara menjalankan pernyataan multi-line dalam debugger Python sendiri (PDB)

157

Jadi saya menjalankan skrip Python di mana saya memanggil debugger Python, PDB dengan menulis:

import ipdb; ipdb.set_trace()

(Versi PDB iPython, meskipun untuk hal ini saya tidak berpikir itu membuat perbedaan; Saya menggunakannya untuk output berwarna saja).

Sekarang, ketika saya sampai ke debugger saya ingin menjalankan pernyataan multi-line seperti jika klausa atau untuk loop tetapi segera setelah saya mengetik

if condition:

dan tekan tombol kembali, saya mendapatkan pesan kesalahan *** SyntaxError: invalid syntax (<stdin>, line 1)

Bagaimana kita bisa menjalankan pernyataan multi-line dalam PDB? Jika tidak memungkinkan apakah ada cara lain untuk tetap mengeksekusi klausa if atau for for?

Mike
sumber

Jawaban:

265

Anda bisa melakukan ini di pdb untuk meluncurkan sesi Python interaktif sementara dengan semua variabel lokal yang tersedia:

(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)
>>> 

Setelah selesai, gunakan Ctrl-D untuk kembali ke prompt pdb biasa.

Hanya saja jangan menekan Ctrl-C, yang akan mengakhiri seluruh sesi pdb.

Marius Gedminas
sumber
46
Tampaknya hal yang sama dapat dicapai dengan menggunakan interactperintah pdb ( seperti yang saya pelajari dari pesan pelacak bug ini ).
gerrit
3
Mengapa yang !dibutuhkan dalam importpernyataan itu?
Indradhanush Gupta
19
Itu mungkin tidak diperlukan, tapi saya punya kebiasaan awalan semua pernyataan Python dengan pdb !, untuk menghindari kecelakaan. Misalnya c = 42dalam pdb akan melanjutkan eksekusi daripada menugaskan ke variabel c.
Marius Gedminas
8
@MariusGedminas hal yang paling membuat frustrasi dengan PDB! Akan lebih baik jika perintah mereka harus diawali ...
Ian Clark
Catatan: Ctrl-D tampaknya menjadi cara yang tepat untuk keluar interactjuga, tetapi itu tidak cocok dengan saya untuk Spyder.
Josiah Yoder
69

Dalam python3 ipdb(dan pdb) memiliki perintah yang disebut berinteraksi . Dapat digunakan untuk:

Mulai juru bahasa interaktif (menggunakan modul kode ) yang namespace globalnya berisi semua nama (global dan lokal) yang ditemukan dalam lingkup saat ini.

Untuk menggunakannya, cukup masukkan interactdi prompt pdb. Di antara hal-hal lain, ini berguna untuk menerapkan kode yang mencakup beberapa baris, dan juga untuk menghindari pemicu yang tidak disengaja dari perintah pdb lainnya.

vaer-k
sumber
2
Ini memberi saya "NameError: nama 'berinteraksi' tidak didefinisikan" ketika melakukan itu.
Jason
1
@jason versi 3.2 atau lebih tinggi
vaer-k
2
Itu menjelaskan. Saya menggunakan python 2.7.
Jason
Hati-hati ini sebenarnya melemparkan kesalahan yang bisa berinteraksi tidak didefinisikan dan keluar dari proses
Camron_Godbout
1
Saya pikir menyarankan untuk menghindari interactadalah saran yang terlalu kuat. 90% ini yang saya butuhkan, dan jauh lebih mudah untuk mengetik daripadafrom IPython import embed; embed()
vaer-k
43

Rekomendasi saya adalah menggunakan embedding IPython.

ipdb> from IPython import embed; embed()
fx-kirin
sumber
2
Jika Anda memiliki nilai tidak didefinisikan kesalahan dalam pemahaman daftar, coba gunakan dari IPython import embed; embed(user_ns=locals()).
fx-kirin
1
ini bekerja jauh lebih baik bagi saya daripada jawaban yang diterima. Sebagai contoh - ini memungkinkan pengeditan multiline yang benar - seperti kembali beberapa baris dan memperbaiki sesuatu, jadi Anda tidak perlu menulis ulang seluruh ekspresi multi-baris Anda lagi ... Saya melewati penduduk setempat sebagai @ fx-kirin disarankan.
ZeDuS
33

Di dalam interpreter atau debugger Python (2.7.1), impor pdb), Anda bisa menjalankan pernyataan multi-baris dengan sintaks berikut.

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

Catatan: Ketika saya di dalam interpreter, saya harus menekan return dua kali sebelum kode akan dieksekusi. Di dalam debugger, bagaimanapun, saya hanya perlu menekan kembali sekali.

Garrett Hyde
sumber
5
Itu tidak memungkinkan menjalankan sesuatu yang lebih dalam dari satu level.
Antony Hatchkins
7

Ada kasus khusus jika Anda ingin beberapa perintah dieksekusi ketika mencapai break point. Lalu ada perintah debugger commands. Ini memungkinkan Anda untuk memasukkan banyak baris perintah dan kemudian mengakhiri seluruh urutan dengan endkata kunci. Lebih banyak dengan (pdb) help commands.

ThomasH
sumber
2

Saya tidak tahu apakah Anda bisa melakukan ini, itu akan menjadi fitur hebat untuk ipdb. Anda dapat menggunakan daftar pemahaman tentu saja, dan menjalankan ekspresi multi-line sederhana seperti:

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

Anda juga dapat menulis beberapa fungsi sebelumnya untuk melakukan apa pun yang perlu Anda lakukan yang biasanya akan mengambil beberapa baris.

Zeekay
sumber
-6

Tulis kode Anda dalam editor teks, lalu tempelkan ke dalam debugger:

if True:
    print('a')

Ini adalah solusi konyol, tetapi juga cepat kotor dan bekerja. Ini bekerja di terminal Linux, tetapi saya tidak yakin apakah itu akan bekerja pada konsol Windows.

bizi
sumber
3
Jujur, saya tidak akan mengatakan bahwa memanggil program eksternal, menulis, menyalin dan menempel cepat , hanya kotor: P
The Scientific Data
4
Ini, tidak bekerja untuk saya, dan kemudian*** SyntaxError: unexpected EOF while parsing
Yash Kant