Python hata ayıklama ipuçları [kapalı]


164

Python hata ayıklama için en iyi ipuçlarınız nelerdir?

Lütfen gerçekte ne yapabileceğini söylemeden sadece belirli bir hata ayıklayıcıyı listelemeyin.

İlişkili


Yanıtlar:


139

PDB

Pdb modülünü kullanabilir, pdb.set_trace()herhangi bir yere yerleştirebilirsiniz ve bir kesme noktası olarak işlev görecektir.

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

Yürütmeye devam etmek için c(veya contveya continue) kullanın .

Pdb kullanarak rasgele Python ifadeleri çalıştırmak mümkündür. Örneğin, bir hata bulursanız, kodu düzeltebilir, ardından çalışan kodda aynı etkiye sahip olmak için bir tür ifadesi yazabilirsiniz

ipdb, IPython için pdb'nin bir sürümüdür . Sekme tamamlama dahil tüm IPython özellikleri ile pdb kullanımına izin verir.

PDB'yi yakalanmayan bir istisnada otomatik olarak çalışacak şekilde ayarlamak da mümkündür .

Pydb , Pdb'nin geliştirilmiş bir versiyonu olarak yazılmıştır. Yararları?


İşte pdb kullanma hakkında bir makale: sontek.net/debugging-python-with-pdb
sontek

Şahsen ipdb'yi daha çok seviyorum .
Sardathrion - SE kötüye karşı

1
Görünüşe göre pydbgr adlı bir pydb
Ehtesh Choudhury 17:13

: Sublime Text kod için piton kesme noktaları eklemek için mükemmel bir eklenti vardır sublime.wbond.net/packages/Python%20Breakpoints
Dennis Golomazov

Bir web uygulaması geliştiriyorsanız myserver.com/pdb, hata ayıklama modunda bir görünüm ekleyin import pdb; pdb.set_trace(). Etkileşimli bir hata ayıklayıcıya sahip olan Flask / Werkzeug kullanıyorsanız, bunu yapan bir görünümünüz de olabilir assert False.
osa

78

http://pypi.python.org/pypi/pudb , tam ekran, konsol tabanlı bir Python hata ayıklayıcısı.

Amacı, modern GUI tabanlı hata ayıklayıcıların tüm özelliklerini daha hafif ve klavye dostu bir pakette sunmaktır. PuDB, bir terminalde kodu yazdığınız ve test ettiğiniz yerde hata ayıklamanıza olanak tanır. Mükemmel (ancak günümüzde eski) DOS tabanlı Turbo Pascal veya C araçlarıyla çalıştıysanız, PuDB'nin kullanıcı arayüzü tanıdık gelebilir.

pudb ekran görüntüsü

Bağımsız komut dosyalarında hata ayıklamak için güzel, sadece çalıştırın

python -m pudb.run my-script.py

Yüklemepip install pudb
congusbongus

40

Pdb kullanıyorsanız, kısayollar için diğer adlar tanımlayabilirsiniz. Bunları kullanıyorum:

# 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

Bu takma adı nasıl tanımlarsınız?
Casebash

9
Bu şeyleri ~ / .pdbrc
Ned Batchelder'e

Windows'ta ~ / _ipython / ipythonrc.ini
fastmultiplication

33

Kerestecilik

Python zaten mükemmel bir yerleşik günlükleme modülüne sahiptir . Günlük şablonunu burada kullanmak isteyebilirsiniz .

Günlüğe kaydetme modülü bir önem düzeyi belirlemenizi sağlar; hata ayıklama sırasında her şeyi günlüğe kaydedebilirsiniz, normal çalışma sırasında ise yalnızca kritik şeyleri kaydedebilirsiniz. Bazı şeyleri kapatabilir ve açabilirsiniz.

Çoğu kişi hata ayıklamak için temel yazdırma deyimlerini kullanır ve ardından yazdırma deyimlerini kaldırır. Onları bırakmak daha iyidir, ancak devre dışı bırakın; başka bir hatanız olduğunda, her şeyi yeniden etkinleştirebilir ve günlüklerinize bakabilirsiniz.

Bu, ağ bağlantısının diğer ucundan önce zaman aşımına uğramadan ve kaybolmadan yanıt vermesi gereken ağ programları gibi, işleri hızlı bir şekilde yapması gereken programlarda hata ayıklamanın en iyi yolu olabilir. Bir hata ayıklayıcıyı tek adımlı hale getirmek için fazla zamanınız olmayabilir; ancak kodunuzun çalışmasına izin verebilir ve her şeyi günlüğe kaydedebilir, daha sonra günlükleri gözleyebilir ve gerçekte ne olduğunu anlayabilirsiniz.

DÜZENLEME: Şablonlar için orijinal URL: http://aymanh.com/python-debugging-techniques

Bu sayfa eksik, bu yüzden onu archive.org'da kaydedilen anlık görüntü referansıyla değiştirdim: http://web.archive.org/web/20120819135307/http://aymanh.com/python-debugging-techniques

Tekrar kaybolması durumunda, bahsettiğim şablonlar. Bu blogdan alınan koddur; Ben yazmadım.

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

Ve işte yukarıdakilerin nasıl kullanılacağına dair açıklaması. Yine, bunun için kredi alamadım:


Varsayılan olarak, kayıt modülü kritik, hata ve uyarı mesajlarını yazdırır. Bunu tüm düzeylerin yazdırılacağı şekilde değiştirmek için şunu kullanın:

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

Debug.log adlı bir dosyaya günlük mesajları göndermek için şunu kullanın:

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


1
Günlüğe kaydetme modülü ile ilgili sorun, Unicode ile yoğun bir şekilde kırılması ve uluslararası bir uygulamada çalışması için çeşitli geçici çözümlere ihtiyaç duymasıdır. Yine de, bu hala Python için en iyi günlükleme çözümüdür.
Jacek Konieczny

"Buraya günlük kaydı şablonu" bağlantısı öldü. Lütfen güncelle.
Mart'ta Yohann

20

Hangi Python satırlarının yürütüldüğünü yazdırmak mümkündür (teşekkürler Geo!). Bunun herhangi bir sayıda uygulaması vardır, örneğin, belirli işlevlerin ne zaman çağrıldığını kontrol etmek için değiştirebilir veya ## gibi bir şey ekleyerek yalnızca belirli satırları izleyebilirsiniz.

code.interact sizi etkileşimli bir konsola götürür

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

Konsol geçmişinize kolayca erişebilmek istiyorsanız şuraya bakın: " Kabukta olduğu gibi bir geçmiş mekanizmasına sahip olabilir miyim? " (Aşağıya bakmak zorunda kalacak).

Yorumlayıcı için otomatik tamamlama etkinleştirilebilir .


19

ipdb, ipython'un muazzamlığı ile pdb gibidir.


5
Ne yapabileceği hakkında daha fazla ayrıntı ekleyebilir misiniz?
Casebash

17

print ifadeleri

  • Bazı kullanıcılar debug_print, kolay devre dışı bırakma için yazdırma yerine bir işlev önerir
  • pprintModül kompleks yapıların çok değerli

3
Her hata ayıklayıcı başarısız olduğunda +1 yazdır arkadaşınızdır, evet debug_print hoş bir ek olacaktır
Anurag Uniyal

Belirli bir bölümü izleyerek çözebileceğimi bildiğim hariç, genellikle önce ilk sonra ikinci hata ayıklamayı yazdırırım
Casebash

4
Aslında log modülü bunu yapar.
e-satis

Doğru, ancak günlüğe kaydetme ayarlanmalıdır.
Onurtan

baskı basit durumlar için ve özellikle küçük başlangıç ​​zamanı olan projeler geliştirirken faydalı olabilir. Diğer tarafta bağımlılık yapabilir ve daha karmaşık senaryolarda pdb veya başka bir hata ayıklayıcı üzerinde kullanmak genellikle baş ağrısına neden olur
vinilios

16

bir komut dosyasında hata ayıklamanın açık yolu

python -m pdb script.py
  • bu komut dosyası bir özel durum oluşturduğunda yararlı olur
  • venen python sürümü ile virtualenv ve pdb komutu kullanılırken kullanışlıdır.

bu komut dosyasının tam olarak nerede olduğunu bilmiyorsanız

python -m pdb ``which <python-script-name>``

15

Pydev

PyDev oldukça iyi bir interaktif hata ayıklayıcıya sahiptir. İfadeleri izle, fareyle değerlendir, iplik ve yığın listelerine ve (neredeyse) modern bir görsel hata ayıklayıcıdan beklediğiniz tüm normal olanaklara sahiptir. Çalışan bir işleme bile ekleyebilir ve uzaktan hata ayıklama yapabilirsiniz.

Diğer görsel hata ayıklayıcılar gibi, çoğunlukla basit problemler için ya da her şeyi denedikten sonra çok karmaşık problemler için yararlı buluyorum. Hala ağır kaldırma işlemlerinin çoğunu kütükleme ile yapıyorum.


Düzenleme ve devam etme yeteneği var mı?
Casebash

@CaseBash hayır değil ama bu özellik planlandı. Onsuz bile, kesme noktalarını ayarlama / ayarlama ve değişken değerlere bakmanın hızı ve kolaylığı hala çok faydalıdır
Jiaaro


12

Winpdb çok güzel ve isminin aksine tamamen çapraz platform.

Çok güzel bir istem tabanlı ve GUI hata ayıklayıcısı var ve uzaktan hata ayıklamayı destekliyor.


@Casebash - daha fazla ayrıntı eklendi
orip

1
+1 Bu, şimdiye kadar bulduğum çoklu iş parçacığını işleyebilen tek python hata ayıklayıcısı.
Lee Netherton

Çoklu iş parçacığının "kullanımı" na dikkat edin - herhangi bir iş parçacığındaki herhangi bir istisna tüm işlemin donmasına neden olur. Farkındaysanız kötü bir şey değil, eğer değilseniz çok acı verici
Walt W

Proje Nisan 2014 itibariyle ölü görünüyor
Alojz Janez

7

Vim'de şu üç bağlantım var:

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>

rpdb2katı bir grafik hata ayıklayıcısı olan WinPDB ile kullanılabilen bir Uzak Python Hata Ayıklayıcısıdır. Çünkü soracağınızı biliyorum, grafiksel bir hata ayıklayıcının yapmasını beklediğim her şeyi yapabilir :)

Kullandığım pdbdan nose.toolsben birim testleri yanı sıra, normal kod hata ayıklama böylece.

Son olarak, F7eşleme bir geri izleme yazdırır (bir istisna yığının tepesine çıktığında aldığınız türe benzer). Birkaç kez daha faydalı buldum.


4

Sınıflarınız için yararlı repr () yöntemleri tanımlama (böylece bir nesnenin ne olduğunu görebilirsiniz) ve repr () veya "% r"% (...) veya "... {0! R} .." biçimini kullanma. (...) hata ayıklama iletilerinizde / günlüklerinizde IMHO etkin hata ayıklamanın anahtarıdır.

Ayrıca, diğer yanıtlarda belirtilen hata ayıklayıcıları repr () yöntemlerini kullanacaktır .


2

Çalışan bir Python uygulamasından yığın izlemesi alma

Burada birkaç numara var . Bunlar

  • Bir yorumlayıcıya girme / sinyal göndererek yığın izlemesi yazdırma
  • Hazırlanmamış bir Python işleminden yığın izlemesi alma
  • Hata ayıklama için yararlı olması amacıyla yorumlayıcıyı bayraklarla çalıştırma

2

Hata ayıklayıcılarda zaman geçirmekten hoşlanmıyorsanız (ve pdbkomut satırı arabiriminin zayıf kullanılabilirliğini takdir etmiyorsanız ), yürütme izlemesini dökebilir ve daha sonra analiz edebilirsiniz. Örneğin:

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

Bu, tüm kaynak setup.py installyürütme satırını dökecektir execution.log.

İzleme çıktısını özelleştirmeyi ve kendi izleyicilerinizi yazmayı kolaylaştırmak için, xtrace modülüne (kamu malı) bazı kod parçalarını bir araya getirdim .


1

Mümkün olduğunda, M-x pdbkaynak düzeyinde hata ayıklama için emacs kullanarak hata ayıklama.


1

Udacity'de Andreas Zeller tarafından " Hata Ayıklama " adlı tam bir çevrimiçi kurs var, hata ayıklama ile ilgili ipuçları:

Ders Özeti

Bu sınıfta programların sistematik olarak nasıl hata ayıklanacağını, hata ayıklama sürecinin nasıl otomatikleştirileceğini ve Python'da çeşitli otomatik hata ayıklama araçlarının nasıl oluşturulacağını öğreneceksiniz.

Neden Bu Kursa Katılmalısınız?

Bu dersin sonunda sistematik hata ayıklama hakkında sağlam bir anlayışa sahip olacak, hata ayıklamayı otomatikleştirmeyi bilecek ve Python'da birkaç işlevsel hata ayıklama aracı oluşturmuş olacaksınız.

Önkoşullar ve Gereksinimler

Udacity CS101 veya daha üst bir seviyede temel programlama ve Python bilgisi gereklidir. Nesneye yönelik programlamanın temel anlayışı yardımcı olur.

Şiddetle tavsiye edilir.


0

çağrı yığınınızı okunabilir bir şekilde yazdırmak için güzel bir grafik yolu istiyorsanız, bu yardımcı programa göz atın: https://github.com/joerick/pyinstrument

Komut satırından çalıştır:

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

Bir modül olarak çalıştırın:

from pyinstrument import Profiler

profiler = Profiler()
profiler.start()

# code you want to profile

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

Django ile çalıştırın:

Sadece eklemek pyinstrument.middleware.ProfilerMiddlewareiçin MIDDLEWARE_CLASSES, sonra da eklemek ?profileProfilcinin etkinleştirmek için istek URL'nin sonuna.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.