Dari apa yang saya baca, ada dua cara untuk men-debug kode dengan Python:
Dengan debugger tradisional seperti
pdb
atauipdb
. Ini mendukung perintah sepertic
untukcontinue
,n
untukstep-over
,s
untukstep-into
dll), tetapi Anda tidak memiliki akses langsung ke IPython shell yang dapat sangat berguna untuk pemeriksaan objek.Menggunakan IPython dengan menyematkan shell IPython dalam kode Anda. Anda dapat melakukannya
from ipython import embed
, lalu gunakanembed()
dalam kode Anda. Ketika program / skrip Anda mencapai sebuahembed()
pernyataan, Anda dimasukkan ke dalam shell IPython. Ini memungkinkan pemeriksaan penuh objek dan pengujian kode Python menggunakan semua barang IPython. Namun, saat menggunakanembed()
Anda tidak bisa lagi selangkah-selangkah melewati kode dengan pintasan keyboard yang praktis.
Apakah ada cara untuk menggabungkan yang terbaik dari kedua dunia? Yaitu
- Mampu selangkah demi selangkah melalui kode Anda dengan pintasan keyboard pdb / ipdb yang praktis.
- Pada langkah seperti itu (misalnya pada pernyataan yang diberikan), memiliki akses ke shell IPython penuh .
IPython debugging seperti pada MATLAB:
Contoh dari jenis "peningkatan debugging" ini dapat ditemukan di MATLAB, di mana pengguna selalu memiliki akses penuh ke mesin / shell MATLAB, dan dia masih bisa selangkah demi selangkah melalui kodenya, menentukan breakpoint bersyarat, dll. Dari apa yang telah saya diskusikan dengan pengguna lain, ini adalah fitur debugging yang paling banyak orang lewatkan ketika berpindah dari MATLAB ke IPython.
Debugging IPython di Emacs dan editor lain:
Saya tidak ingin membuat pertanyaan terlalu spesifik, tetapi saya bekerja sebagian besar di Emacs, jadi saya bertanya-tanya apakah ada cara untuk membawa fungsi ini ke dalamnya. Idealnya , Emacs (atau editor) akan memungkinkan programmer untuk mengatur breakpoints di mana saja pada kode dan berkomunikasi dengan penerjemah atau debugger untuk menghentikannya di lokasi pilihan Anda, dan membawa ke penerjemah IPython penuh di lokasi itu.
!
perintah yang mengeksekusi perintah python di breakpointJawaban:
Anda dapat menggunakan
%pdb
sihir IPython . Panggil saja%pdb
IPython dan ketika kesalahan terjadi, Anda secara otomatis dijatuhkan keipdb
. Meskipun Anda tidak memiliki langkah segera, Anda masukipdb
setelahnya.Ini membuat debugging fungsi individu mudah, karena Anda bisa memuat file dengan
%load
dan kemudian menjalankan fungsi. Anda dapat memaksa kesalahan denganassert
posisi yang tepat.%pdb
adalah sihir garis. Sebut saja sebagai%pdb on
,%pdb 1
,%pdb off
atau%pdb 0
. Jika dipanggil tanpa argumen itu berfungsi sebagai toggle.sumber
ipython --pdb file.py -- args
dan dijatuhkan ke ipdb dengan pengecualian. Mungkin layak ditambahkan ke jawabannya.Bagaimana dengan ipdb.set_trace ()? Dalam kode Anda:
import ipdb; ipdb.set_trace()
pembaruan : sekarang dengan Python 3.7, kita dapat menulis
breakpoint()
. Ia bekerja sama, tetapi juga mematuhiPYTHONBREAKPOINT
variabel lingkungan. Fitur ini berasal dari PEP ini .Ini memungkinkan untuk inspeksi penuh kode Anda, dan Anda memiliki akses ke perintah seperti
c
(melanjutkan),n
(jalankan baris berikutnya),s
(masuk ke metode pada titik) dan seterusnya.Lihat repo ipdb dan daftar perintah . IPython sekarang disebut (sunting: bagian dari) Jupyter .
ps: perhatikan bahwa perintah ipdb lebih diutamakan daripada kode python. Jadi untuk menulis yang
list(foo)
Anda butuhkanprint list(foo)
.Juga, jika Anda menyukai ipython prompt (emacs dan vim mode, histori, penyelesaian, ...) mudah untuk mendapatkan yang sama untuk proyek Anda karena didasarkan pada toolkit python prompt .
sumber
ipdb
di Emacs menggunakanRealGUD
danisend-mode
untuk melakukan persis apa yang diminta OP.breakpoint()
sangat bagus. Di PyCharm bahkan menjatuhkan Anda ke dalam debugger PyCharm. Ini juga cara cepat untuk memasukkan debugger PyCharm dari fungsi yang disisipkan ke konsol.(Pembaruan pada 28 Mei 2016) Menggunakan RealGUD di Emacs
Bagi siapa pun di Emacs, utas ini menunjukkan cara menyelesaikan semua yang dijelaskan dalam OP (dan banyak lagi) menggunakan
ipdb
).isend-mode
.Kombinasi kedua paket ini sangat kuat dan memungkinkan seseorang untuk menciptakan kembali persis perilaku yang dijelaskan dalam OP dan melakukan lebih banyak lagi.
Info lebih lanjut tentang artikel wiki dari RealGUD untuk ipdb.
Jawaban asli:
Setelah mencoba berbagai metode untuk men-debug Python, termasuk semua yang disebutkan dalam utas ini, salah satu cara yang saya sukai untuk men-debug Python dengan IPython adalah dengan shell yang tertanam.
Mendefinisikan shell IPython tertanam yang kustom:
Tambahkan berikut ini pada skrip ke Anda
PYTHONPATH
, sehingga metodeipsh()
menjadi tersedia.Kemudian, setiap kali saya ingin men-debug sesuatu dalam kode saya, saya menempatkan
ipsh()
tepat di lokasi di mana saya perlu melakukan pemeriksaan objek, dll. Misalnya, katakan saya ingin men-debug dimy_function
bawah iniMenggunakannya:
dan kemudian saya memohon
my_function(2)
dalam salah satu cara berikut:Terlepas dari bagaimana saya memintanya, penerjemah berhenti di baris yang mengatakan
ipsh()
. Setelah selesai, Anda bisa melakukannyaCtrl-D
dan Python akan melanjutkan eksekusi (dengan pembaruan variabel apa pun yang Anda buat). Perhatikan bahwa, jika Anda menjalankan kode dari IPython biasa, shell IPython (kasus 2 di atas), shell IPython yang baru akan disarangkan di dalam yang Anda gunakan, yang benar-benar baik-baik saja, tetapi perlu diperhatikan. Bagaimanapun, begitu penerjemah berhenti di lokasiipsh
, saya dapat memeriksa nilaia
(yang2
), melihat fungsi dan objek apa yang didefinisikan, dllMasalah:
Solusi di atas dapat digunakan untuk menghentikan Python di mana pun Anda inginkan dalam kode Anda, dan kemudian menjatuhkan Anda ke penerjemah IPython sepenuhnya. Sayangnya itu tidak memungkinkan Anda menambah atau menghapus breakpoints setelah Anda menjalankan skrip, yang sangat membuat frustrasi. Menurut pendapat saya, ini adalah satu - satunya hal yang mencegah IPython menjadi alat debugging yang bagus untuk Python.
Yang terbaik yang dapat Anda lakukan untuk saat ini:
Solusinya adalah menempatkan
ipsh()
apriori di lokasi yang berbeda di mana Anda ingin juru bahasa Python meluncurkan shell IPython (yaitu abreakpoint
). Anda kemudian dapat "melompat" di antara "breakpoint" berbeda yang ditentukan sebelumnya, dengan kode kerasCtrl-D
, yang akan keluar dari shell IPython yang tertanam saat ini dan berhenti lagi setiap kali penerjemah menghantam panggilan berikutnyaipsh()
.Jika Anda menggunakan rute ini, salah satu cara untuk keluar dari "mode debugging" dan mengabaikan semua breakpoints berikutnya, adalah dengan menggunakan
ipshell.dummy_mode = True
yang akan membuat Python mengabaikan instantiations berikutnya dariipshell
objek yang kita buat di atas.sumber
import inspect
sebelum berfungsi. Kustomisasi baris perintah tampaknya rusak untuk saya.import ipdb; ipdb.set_trace()
? Mungkin saya melewatkan sesuatu, tetapi saya tidak melihat keuntungan dari metode Anda yang jauh lebih rumit.Anda dapat memulai sesi IPython dari pudb dan kembali ke sesi debug yang Anda inginkan.
BTW, ipdb menggunakan IPython di belakang layar dan Anda benar-benar dapat menggunakan fungsionalitas IPython seperti penyelesaian TAB dan perintah ajaib (yang dimulai dengan
%
). Jika Anda OK dengan ipdb, Anda bisa memulainya dari IPython menggunakan perintah seperti%run
dan%debug
. Sesi ipdb sebenarnya lebih baik daripada IPython biasa dalam arti Anda dapat naik dan turun di tumpukan jejak dll. Apa yang hilang di ipdb untuk "inspeksi objek"?Juga, python.el yang dibundel dengan Emacs> = 24.3 memiliki dukungan ipdb yang bagus.
sumber
M-x ansi-term
buffer terpisah , dan kemudian saya menggunakan mode-isend untuk mengikat buffer sumber saya ke buffer IPython sehingga saya dapat mengirim kode ke interpreter IPython dengan pintasan keyboard yang secara otomatis mengirimkan%paste
keajaiban ke buffer IPython. Ini memungkinkan saya untuk dengan cepat menguji wilayah di IPython. Saya selalu menjalankan program saya dari shell IPython inirun
dan menggunakannyaembed()
untuk berhenti.ipdb
sesi debug menggunakanpython.el
dan memiliki hal-hal sepertisend-region
dll ke shell yang sesuai? Secara umum, di mana saya dapat menemukan lebih banyak info tentang ini?%run
atau%debug
. Saya kiraimport ipdb; ipdb.set_trace()
bekerja juga. Saya tidak berpikir Anda dapat mengirim banyak baris ke ipdb. Itu batasan ipdb. Tapi mungkin%paste
triknya berhasil. Anda mungkin ingin mengirim permintaan fitur ke IPython dev.Sepertinya pendekatan dalam jawaban @ gaborous sudah usang .
Pendekatan baru tampaknya:
sumber
ipdb
pernyataan dalam shell ipython, saat debugging?Awalan "!" simbol untuk perintah yang Anda ketik pdb tampaknya memiliki efek yang sama dengan melakukan sesuatu di shell IPython. Ini berfungsi untuk mengakses bantuan untuk fungsi tertentu, atau bahkan nama variabel. Mungkin ini akan membantu Anda sampai batas tertentu. Sebagai contoh,
Tetapi! Help (numpy.transpose) akan memberi Anda halaman bantuan yang diharapkan di numpy.transpose. Demikian pula untuk nama variabel, misalkan Anda memiliki variabel l, mengetik "l" di pdb mencantumkan kode, tetapi! L mencetak nilai l.
sumber
Apakah Anda mencoba kiat ini ?
sumber
Anda bisa mulai
IPython
dari dalamipdb
!Menginduksi
ipdb
debugger 1 :Masukkan IPython dari dalam di
ipdb>
konsol 2 :Kembali ke
ipdb>
konsol dari dalamIPython
:Jika Anda cukup beruntung menggunakan Emacs, hal-hal dapat dibuat lebih nyaman!
Ini membutuhkan penggunaan
M-x shell
. Menggunakanyasnippet
dan bm , tentukan cuplikan berikut. Ini akan menggantikan teksipdb
dalam editor denganset-trace
baris. Setelah memasukkan potongan, garis akan disorot sehingga mudah terlihat dan dinavigasi. GunakanM-x bm-next
untuk menavigasi.1 Semua dalam satu baris untuk penghapusan mudah. Karena
imports
hanya terjadi sekali, formulir ini memastikanipdb
akan diimpor ketika Anda membutuhkannya tanpa biaya tambahan.2 Anda dapat menyimpan sendiri beberapa pengetikan dengan mengimpor di
IPython
dalam.pdbrc
file Anda :Ini memungkinkan Anda untuk hanya menelepon
embed()
dari dalamipdb
(tentu saja, hanya ketika IPython diinstal).sumber
Salah satu opsi adalah menggunakan IDE seperti Spyder yang seharusnya memungkinkan Anda untuk berinteraksi dengan kode Anda saat debugging (sebenarnya menggunakan konsol IPython). Faktanya, Spyder sangat mirip MATLAB, yang saya duga disengaja. Itu termasuk pengawas variabel, pengeditan variabel, akses built-in ke dokumentasi, dll.
sumber
jawaban yang tepat, mudah, keren, tepat untuk pertanyaannya adalah menggunakan% run macro dengan -d flag.
sumber
%save /tmp/foo.py x-y
Kode yang ingin saya jalankan dan debug dan kemudian%run -d /tmp/foo.py
mengatur breakpoint di mana pun saya suka. Jawaban bagus!Jika Anda mengetikkan exit () di konsol embed () kode lanjutkan dan pergi ke baris embed () berikutnya.
sumber
The Pyzo IDE memiliki kemampuan yang sama seperti OP minta. Anda tidak harus memulai dalam mode debug. Sama halnya dengan MATLAB, perintah dieksekusi di shell. Ketika Anda mengatur break-point di beberapa baris kode sumber, IDE menghentikan eksekusi di sana dan Anda dapat men-debug dan mengeluarkan perintah IPython biasa juga.
Namun tampaknya langkah-ke-dalam (belum?) Berfungsi dengan baik (yaitu berhenti di satu baris dan kemudian melangkah ke fungsi lain) kecuali jika Anda mengatur break-point lain.
Namun, datang dari MATLAB, ini sepertinya solusi terbaik yang saya temukan.
sumber
Dari python 3.2, Anda memiliki
interact
perintah, yang memberi Anda akses ke ruang perintah python / ipython penuh.sumber
Menjalankan dari dalam IPython-shell dan breakpoint yang diatur Emacs melalui pdb.set_trace () harus bekerja.
Diperiksa dengan python-mode.el, Mx ipython RET dll.
sumber
Mengembangkan Kode Baru
Debugging di dalam IPython
Contoh Sel:
Debugging Kode yang Ada
IPython di dalam debugging
pytest ... --pdbcls=IPython.terminal.debugger:TerminalPdb --pdb
breakpoint()
,python -m ipdb
, dllPikiran tentang Python
Saya setuju dengan OP bahwa banyak hal yang MATLAB lakukan dengan baik Python masih belum memiliki dan benar-benar harus karena hampir semua hal dalam bahasa mendukung kecepatan pengembangan daripada kecepatan produksi. Mungkin suatu hari nanti saya akan berkontribusi lebih dari perbaikan bug sepele untuk CPython.
https://github.com/ipython/ipython/commit/f042f3fea7560afcb518a1940daa46a72fbcfa68
Lihat juga Apakah mungkin menjalankan perintah di IPython dengan debugging?
sumber