Kiat debugging Python [ditutup]

164

Apa tips terbaik Anda untuk debugging Python?

Tolong jangan hanya daftar debugger tertentu tanpa mengatakan apa yang sebenarnya bisa dilakukan.

Terkait

tidak diketahui
sumber

Jawaban:

139

PDB

Anda dapat menggunakan modul pdb, masukkan di pdb.set_trace()mana saja dan itu akan berfungsi sebagai breakpoint.

>>> import pdb
>>> a="a string"
>>> pdb.set_trace()
--Return--
> <stdin>(1)<module>()->None
(Pdb) p a
'a string'
(Pdb)

Untuk melanjutkan penggunaan eksekusi c(atau contatau continue).

Dimungkinkan untuk mengeksekusi ekspresi Python sewenang-wenang menggunakan pdb. Misalnya, jika Anda menemukan kesalahan, Anda dapat memperbaiki kode, lalu ketikkan ekspresi tipe untuk memiliki efek yang sama dalam kode yang sedang berjalan

ipdb adalah versi pdb untuk IPython . Ini memungkinkan penggunaan pdb dengan semua fitur IPython termasuk penyelesaian tab.

Dimungkinkan juga untuk mengatur pdb agar berjalan secara otomatis pada pengecualian yang tidak tertangkap.

Pydb ditulis untuk menjadi versi Pdb yang disempurnakan. Manfaat?

ghostdog74
sumber
Berikut adalah artikel tentang menggunakan pdb: sontek.net/debugging-python-with-pdb
sontek
Secara pribadi, saya lebih suka ipdb .
Sardathrion - terhadap penyalahgunaan SE
1
Rupanya ada penulisan ulang pydb yang disebut pydbgr
Ehtesh Choudhury
SublimeText memiliki plugin yang bagus untuk menambahkan python breakpoints ke kode: sublime.wbond.net/packages/Python%20Breakpoints
Dennis Golomazov
Jika Anda mengembangkan aplikasi web, tambahkan tampilan myserver.com/pdbdalam mode debug yang cukup import pdb; pdb.set_trace(). Jika Anda menggunakan Flask / Werkzeug yang memiliki debugger interaktif, Anda juga dapat memiliki pandangan yang baru saja melakukannya assert False.
Osa
78

http://pypi.python.org/pypi/pudb , layar penuh, debugger Python berbasis konsol.

Tujuannya adalah untuk menyediakan semua kemudahan debuggers berbasis GUI modern dalam paket yang lebih ringan dan ramah keyboard. PuDB memungkinkan Anda untuk men-debug kode di tempat Anda menulis dan mengujinya - di terminal. Jika Anda telah bekerja dengan Turbo Pascal atau C tools berbasis DOS yang sangat baik (tapi kuno), UI PuDB mungkin terlihat familier.

tangkapan layar pudb

Bagus untuk debugging skrip mandiri, jalankan saja

python -m pudb.run my-script.py
miku
sumber
Instal denganpip install pudb
congusbongus
40

Jika Anda menggunakan pdb, Anda dapat menentukan alias untuk pintasan. Saya menggunakan ini:

# Ned's .pdbrc

# Print a dictionary, sorted. %1 is the dict, %2 is the prefix for the names.
alias p_ for k in sorted(%1.keys()): print "%s%-15s= %-80.80s" % ("%2",k,repr(%1[k]))

# Print the instance variables of a thing.
alias pi p_ %1.__dict__ %1.

# Print the instance variables of self.
alias ps pi self

# Print the locals.
alias pl p_ locals() local:

# Next and list, and step and list.
alias nl n;;l
alias sl s;;l

# Short cuts for walking up and down the stack
alias uu u;;u
alias uuu u;;u;;u
alias uuuu u;;u;;u;;u
alias uuuuu u;;u;;u;;u;;u
alias dd d;;d
alias ddd d;;d;;d
alias dddd d;;d;;d;;d
alias ddddd d;;d;;d;;d;;d
Ned Batchelder
sumber
Bagaimana Anda mendefinisikan alias ini?
Casebash
9
Taruh barang ini di ~ / .pdbrc
Ned Batchelder
di windows Anda bisa memasukkannya ke ~ / _ipython / ipythonrc.ini
fastmultiplication
33

Penebangan

Python sudah memiliki modul logging bawaan yang luar biasa . Anda mungkin ingin menggunakan templat pendataan di sini .

Modul logging memungkinkan Anda menentukan tingkat kepentingan; selama debugging Anda dapat mencatat semuanya, sementara selama operasi normal Anda mungkin hanya mencatat hal-hal penting. Anda dapat mematikan dan menghidupkan berbagai hal.

Kebanyakan orang hanya menggunakan pernyataan cetak dasar untuk debug, dan kemudian menghapus pernyataan cetak. Lebih baik meninggalkannya, tetapi nonaktifkan; kemudian, ketika Anda memiliki bug lain, Anda bisa mengaktifkan kembali semuanya dan melihat log Anda.

Ini bisa menjadi cara terbaik untuk men-debug program yang perlu melakukan sesuatu dengan cepat, seperti program jaringan yang perlu merespons sebelum ujung koneksi jaringan yang lain mati dan hilang. Anda mungkin tidak punya banyak waktu untuk satu langkah debugger; tetapi Anda bisa membiarkan kode Anda berjalan, dan mencatat semuanya, lalu memeriksa log dan mencari tahu apa yang sebenarnya terjadi.

EDIT: URL asli untuk templat adalah: http://aymanh.com/python-debugging-techniques

Halaman ini tidak ada sehingga saya menggantinya dengan referensi ke snapshot yang disimpan di archive.org: http://web.archive.org/web/20120819135307/http://aymanh.com/python-debugging-techniques

Jika hilang lagi, berikut adalah templat yang saya sebutkan. Ini kode yang diambil dari blog; Saya tidak menulisnya.

import logging
import optparse

LOGGING_LEVELS = {'critical': logging.CRITICAL,
                  'error': logging.ERROR,
                  'warning': logging.WARNING,
                  'info': logging.INFO,
                  'debug': logging.DEBUG}

def main():
  parser = optparse.OptionParser()
  parser.add_option('-l', '--logging-level', help='Logging level')
  parser.add_option('-f', '--logging-file', help='Logging file name')
  (options, args) = parser.parse_args()
  logging_level = LOGGING_LEVELS.get(options.logging_level, logging.NOTSET)
  logging.basicConfig(level=logging_level, filename=options.logging_file,
                      format='%(asctime)s %(levelname)s: %(message)s',
                      datefmt='%Y-%m-%d %H:%M:%S')

  # Your program goes here.
  # You can access command-line arguments using the args variable.

if __name__ == '__main__':
  main()

Dan inilah penjelasannya tentang cara menggunakan hal di atas. Sekali lagi, saya tidak mendapatkan kredit untuk ini:


Secara default, modul logging mencetak pesan kritis, kesalahan, dan peringatan. Untuk mengubah ini sehingga semua level dicetak, gunakan:

$ ./your-program.py --logging=debug

Untuk mengirim pesan log ke file bernama debug.log, gunakan:

$ ./your-program.py --logging-level=debug --logging-file=debug.log

steveha
sumber
1
Masalah dengan modul logging adalah sangat rusak dengan Unicode dan berbagai solusi diperlukan untuk membuatnya bekerja dalam aplikasi yang diinternasionalkan. Padahal, ini masih merupakan solusi logging terbaik untuk Python.
Jacek Konieczny
Tautan "templat templat di sini" sudah mati. Mohon perbarui.
Yohann
20

Dimungkinkan untuk mencetak garis Python apa yang dieksekusi (terima kasih Geo!). Ini memiliki sejumlah aplikasi, misalnya, Anda dapat memodifikasinya untuk memeriksa kapan fungsi tertentu dipanggil atau menambahkan sesuatu seperti ## membuatnya hanya melacak baris tertentu.

code.interact membawa Anda ke konsol interaktif

import code; code.interact(local=locals())

Jika Anda ingin dapat dengan mudah mengakses riwayat konsol Anda lihat: " Dapatkah saya memiliki mekanisme riwayat seperti di shell? " ( Harus melihat ke bawah untuk itu).

Pengisian otomatis dapat diaktifkan untuk penerjemah .

Casebash
sumber
19

ipdb seperti pdb, dengan kehebatan ipython.

Alex Gaynor
sumber
5
Bisakah Anda menambahkan detail lebih lanjut tentang apa yang bisa dilakukan?
Casebash
17

print pernyataan

  • Beberapa orang merekomendasikan debug_printfungsi alih-alih mencetak agar mudah dinonaktifkan
  • The pprintmodul sangat berharga untuk struktur yang kompleks
hasen j
sumber
3
+1 ketika setiap debugger gagal, cetak adalah teman Anda, ya debug_print akan menjadi tambahan yang bagus
Anurag Uniyal
Saya biasanya mencetak pertama kemudian men-debug kedua kecuali ketika saya tahu saya akan dapat menyelesaikannya dengan menelusuri bagian tertentu
Casebash
4
Sebenarnya modul log tidak hanya itu.
e-satis
Benar, tetapi logging harus diatur. Saya akan belajar bagaimana menggunakan modul setelah penghargaan
Casebash
cetak dapat bermanfaat untuk kasus-kasus sederhana dan terutama ketika mengembangkan proyek dengan waktu startup yang kecil. Di sisi lain itu bisa membuat ketagihan dan menggunakannya lebih dari pdb atau debugger lain dalam skenario yang lebih kompleks biasanya akan menyebabkan Anda sakit kepala
vinilios
16

cara yang jelas untuk men-debug skrip

python -m pdb script.py
  • berguna ketika skrip itu menimbulkan pengecualian
  • berguna saat menggunakan perintah virtualenv dan pdb tidak berjalan dengan versi python venvs.

jika Anda tidak tahu persis di mana skrip itu berada

python -m pdb ``which <python-script-name>``
vinilios
sumber
15

PyDev

PyDev memiliki debugger interaktif yang cukup bagus. Ini memiliki ekspresi tontonan, arahkan untuk mengevaluasi, utas dan susun daftar dan (hampir) semua fasilitas yang biasa Anda harapkan dari debugger visual modern. Anda bahkan dapat melampirkan ke proses yang sedang berjalan dan melakukan debugging jarak jauh.

Namun, seperti para pengalih perhatian visual lainnya, saya merasakan manfaatnya terutama untuk masalah sederhana, atau untuk masalah yang sangat rumit setelah saya mencoba yang lain. Saya masih melakukan sebagian besar pengangkatan dengan logging.

itsadok
sumber
Apakah ia memiliki kemampuan untuk mengedit dan melanjutkan?
Casebash
@CaseBash tidak, tapi fitur itu sudah direncanakan. Bahkan tanpa itu sekalipun, kecepatan dan kemudahan pengaturan / unsetting breakpoints dan melihat melalui nilai-nilai variabel masih sangat berguna
Jiaaro
12

Winpdb sangat bagus, dan bertentangan dengan namanya itu sepenuhnya lintas platform.

Ia memiliki debugger berbasis GUI dan prompt yang sangat bagus , dan mendukung debugging jarak jauh.

orip
sumber
@Casebash - menambahkan rincian lebih lanjut
orip
1
+1 Ini adalah satu-satunya debugger python yang saya temukan sejauh ini yang dapat menangani multi-threading.
Lee Netherton
Hati-hati dengan "penanganannya" multi-threading - pengecualian apa pun di utas apa pun menyebabkan seluruh proses membeku. Bukan hal yang buruk jika Anda menyadarinya, sangat menyakitkan jika Anda tidak
Walt W
Proyek ini terlihat mati pada April 2014
Alojz Janez
7

Di Vim, saya punya tiga ikatan ini:

map <F9> Oimport rpdb2; rpdb2.start_embedded_debugger("asdf") #BREAK<esc>
map <F8> Ofrom nose.tools import set_trace; set_trace() #BREAK<esc>
map <F7> Oimport traceback, sys; traceback.print_exception(*sys.exc_info()) #TRACEBACK<esc>

rpdb2adalah Remote Python Debugger, yang dapat digunakan dengan WinPDB, debugger grafis yang solid. Karena saya tahu Anda akan bertanya, itu dapat melakukan semua yang saya harapkan dilakukan oleh debugger grafis :)

Saya menggunakan pdbdari nose.toolssehingga saya bisa men-debug unit test serta kode normal.

Akhirnya, F7pemetaan akan mencetak traceback (mirip dengan jenis yang Anda dapatkan ketika pengecualian muncul di bagian atas tumpukan). Saya merasa ini sangat berguna lebih dari beberapa kali.

David Wolever
sumber
4

Mendefinisikan metode repr () yang berguna untuk kelas Anda (sehingga Anda dapat melihat apa objek itu) dan menggunakan repr () atau "% r"% (...) atau "... {0! R} ..". (...) di pesan / log debug Anda adalah IMHO kunci untuk debugging yang efisien.

Selain itu, para penentang yang disebutkan dalam jawaban lain akan menggunakan metode repr ().

Jacek Konieczny
sumber
2

Mendapatkan jejak tumpukan dari aplikasi Python yang sedang berjalan

Ada beberapa trik di sini . Ini termasuk

  • Membobol juru bahasa / mencetak jejak tumpukan dengan mengirim sinyal
  • Mendapatkan tumpukan jejak dari proses Python yang tidak siap
  • Menjalankan interpreter dengan flag untuk membuatnya berguna untuk debugging
Casebash
sumber
2

Jika Anda tidak suka menghabiskan waktu di debugger (dan tidak menghargai kegunaan pdbantarmuka baris perintah yang buruk ), Anda dapat membuang jejak eksekusi dan menganalisisnya nanti. Sebagai contoh:

python -m trace -t setup.py install > execution.log

Ini akan membuang semua baris sumber setup.py installeksekusi ke execution.log.

Untuk membuatnya lebih mudah untuk menyesuaikan keluaran jejak dan menulis pelacak Anda sendiri, saya mengumpulkan beberapa potongan kode ke modul xtrace (domain publik).

techtonik anatoly
sumber
1

Jika memungkinkan, saya men-debug menggunakan M-x pdbemacs untuk debugging tingkat sumber.

themis
sumber
1

Ada kursus online lengkap yang disebut " Software Debugging " oleh Andreas Zeller di Udacity, dikemas dengan tips tentang debugging:

Ringkasan Kursus

Di kelas ini Anda akan belajar cara debug program secara sistematis, cara mengotomatiskan proses debug dan membangun beberapa alat debug otomatis dengan Python.

Mengapa Mengikuti Kursus Ini?

Pada akhir kursus ini Anda akan memiliki pemahaman yang kuat tentang debugging sistematis, akan tahu bagaimana mengotomatiskan debugging dan akan membangun beberapa alat debugging fungsional dengan Python.

Prasyarat dan Persyaratan

Diperlukan pengetahuan dasar tentang pemrograman dan Python pada level Udacity CS101. Pemahaman dasar pemrograman berorientasi objek sangat membantu.

Sangat dianjurkan.

Udi
sumber
0

jika Anda ingin cara grafis yang bagus untuk mencetak tumpukan panggilan Anda dengan cara yang dapat dibaca, lihat utilitas ini: https://github.com/joerick/pyinstrument

Jalankan dari baris perintah:

python -m pyinstrument myscript.py [args...]

Jalankan sebagai modul:

from pyinstrument import Profiler

profiler = Profiler()
profiler.start()

# code you want to profile

profiler.stop()
print(profiler.output_text(unicode=True, color=True))

Jalankan dengan Django:

Cukup tambahkan pyinstrument.middleware.ProfilerMiddlewareke MIDDLEWARE_CLASSES, kemudian menambahkan ?profileke akhir URL permintaan untuk mengaktifkan profiler.

Kandang kelinci
sumber