Pythonデバッグのヒント[終了]


164

Pythonをデバッグするための最良のヒントは何ですか?

実際に何ができるかを言わずに、特定のデバッガーだけをリストしないでください。

関連する


回答:


139

PDB

pdbモジュールを使用してpdb.set_trace()どこにでも挿入でき、ブレークポイントとして機能します。

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

実行を継続するには、c(またはcontまたはcontinue)を使用します。

pdbを使用して任意のPython式を実行することが可能です。たとえば、間違いを見つけた場合は、コードを修正してから、型式を入力して、実行中のコードで同じ効果を得ることができます

ipdbは、IPython用のpdbのバージョンです。タブ補完を含むすべてのIPython機能でpdbを使用できます。

キャッチされなかった例外で自動的に実行されるようpdb設定することもできます。

Pydbは、Pdbの拡張バージョンとして作成されました。利点?


これは、pdbの使用に関する記事です:sontek.net/debugging-python-with-pdb
sontek

個人的には、ipdbの方が好きです。
サルダトリオン-

1
どうやらpydbgrと呼ばれるpydbの
Ehtesh Choudhury

SublimeTextには、Pythonブレークポイントをコードに追加するための優れたプラグインがあります。sublime.wbond.net/ packages / Python %20Breakpoints
Dennis Golomazov

Webアプリケーションを開発している場合はmyserver.com/pdb、単に実行するデバッグモードのビューを追加しimport pdb; pdb.set_trace()ます。インタラクティブなデバッガーを備えたFlask / Werkzeugを使用している場合は、単にそうするだけのビューを持つこともできますassert False
osa

78

http://pypi.python.org/pypi/pudb、フルスクリーンのコンソールベースのPythonデバッガ。

その目標は、より軽量でキーボードフレンドリーなパッケージで最新のGUIベースのデバッガーのすべての優れた機能を提供することです。PuDBを使用すると、コードを記述してテストする場所で、ターミナルでコードをデバッグできます。優れた(最近は古くなっている)DOSベースのTurbo PascalまたはCツールを使用したことがあれば、PuDBのUIは見慣れたものになるでしょう。

pudbスクリーンショット

スタンドアロンスクリプトのデバッグに最適です。実行するだけです

python -m pudb.run my-script.py

インストールpip install pudb
congusbongus 2014

40

pdbを使用している場合は、ショートカットのエイリアスを定義できます。私はこれらを使用します:

# 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

これらのエイリアスをどのように定義しますか?
Casebash 2009年

9
これを〜/ .pdbrcに入れてください
Ned Batchelder

Windowsでは、〜/ _ipython / ipythonrc.iniに配置できます
fastmultiplication

33

ロギング

Pythonにはすでに優れた組み込みロギングモジュールがありますここでロギングテンプレートを使用できます

ロギングモジュールでは、重要度のレベルを指定できます。デバッグ中はすべてを記録できますが、通常の操作中は重要なもののみを記録できます。オフとオンを切り替えることができます。

ほとんどの人は、基本的な印刷ステートメントを使用してデバッグし、印刷ステートメントを削除します。そのままにして、無効にすることをお勧めします。その後、別のバグがある場合は、すべてを再度有効にして、ログを確認できます。

これは、ネットワーク接続のもう一方の端がタイムアウトして終了する前に応答する必要があるネットワークプログラムなど、処理をすばやく実行する必要があるプログラムをデバッグするための最良の方法です。デバッガをシングルステップする時間があまりない場合があります。ただし、コードを実行してすべてをログに記録し、ログを調べて実際に何が起こっているのかを把握することができます。

編集:テンプレートの元のURLは、http//aymanh.com/python-debugging-techniquesでした。

このページは見つからないので、archive.orgに保存されているスナップショットへの参照に置き換えました。http//web.archive.org/web/20120819135307/http//aymanh.com/python-debugging-techniques

それが再び消える場合のために、ここで私が言及したテンプレートがあります。これはブログから抜粋したコードです。書きませんでした。

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

そして、これが上記の使い方の彼の説明です。繰り返しますが、私はこれの功績はありません。


デフォルトでは、ロギングモジュールはクリティカル、エラー、警告のメッセージを出力します。すべてのレベルが印刷されるようにこれを変更するには、以下を使用します。

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

debug.logというファイルにログメッセージを送信するには、次のコマンドを使用します。

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


1
ロギングモジュールの問題は、Unicodeで大幅に機能しなくなり、国際化されたアプリケーション内で機能させるにはさまざまな回避策が必要になることです。ただし、これはまだPythonの最良のロギングソリューションです。
Jacek Konieczny、2010

「ここにロギングテンプレート」というリンクは無効です。更新してください。
Yohann 2013年

20

実行されたPython行を出力することができます(Geoに感謝します!)。これには任意の数のアプリケーションがあります。たとえば、特定の関数が呼び出されたときにチェックするように変更したり、##のようなものを追加して特定の行のみを追跡したりできます。

code.interactを使用すると、インタラクティブコンソールに移動します

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

コンソールの履歴に簡単にアクセスできるようにしたい場合は、シェルのような履歴メカニズムを使用できますか?」(それを見下ろす必要があります)。

インタープリターに対してオートコンプリートを有効にできます。



17

print ステートメント

  • 一部の人々debug_printは簡単に無効にするために印刷の代わりに機能をお勧めします
  • pprintモジュールは、複雑な構造のために非常に貴重です

3
+1すべてのデバッガーが失敗した場合、printはあなたの友達です、そうですdebug_printは素晴らしい追加になるでしょう
Anurag Uniyal

私は一般的に、私は時を除いて二デバッグ、最初の印刷を知っている私は特定のセクションをトレースすることによって解決することができるようになります
Casebash

4
実際、ログモジュールはまさにそれを行います。
e-satis、

本当ですが、ロギングを設定する必要があります。優等賞の後にモジュールの使用方法を学ぶ
Casebash、2009年

printは、単純なケース、特に起動時間が短いプロジェクトを開発する場合に役立ちます。一方、中毒になる可能性があり、より複雑なシナリオでpdbまたは他のデバッガーを介して使用すると、通常、頭痛の種になります
vinilios

16

スクリプトをデバッグする明白な方法

python -m pdb script.py
  • そのスクリプトが例外を発生させるときに役立ちます
  • virtualenvを使用していて、pdbコマンドがvenvs pythonバージョンで実行されていない場合に便利です。

そのスクリプトの場所が正確にわからない場合

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

15

PyDev

PyDevには非常に優れたインタラクティブデバッガがあります。これには、ウォッチ式、ホバーツーエバリュエーション、スレッドおよびスタックのリスト、および(ほぼ)最新のビジュアルデバッガーに期待される通常のすべての設備が含まれています。実行中のプロセスにアタッチして、リモートデバッグを行うこともできます。

ただし、他のビジュアルデバッガーと同様に、主に単純な問題や、他のすべてを試した後の非常に複雑な問題に役立ちます。私はまだ、ほとんどの面倒な作業をログに記録しています。


編集して続行する機能はありますか?
Casebash 2009年

@CaseBashいいえ、そうではありませんが、その機能は計画されています。それがなくても、ブレークポイントの設定/設定解除と変数値の確認の速度と使いやすさは、依然として非常に便利です
Jiaaro


12

Winpdbは非常に優れており、その名前に反して、完全にクロスプラットフォームです。

それは非常に素晴らしい、プロンプトベースの持っている GUIデバッガ、およびサポートは、リモートデバッグ。


@Casebash -詳細を追加
のoriP

1
+1これは、マルチスレッドを処理できる唯一のpythonデバッガです。
Lee Netherton 2012

マルチスレッドの「処理」に注意してください。どのスレッドでも例外があると、プロセス全体がフリーズします。気づいていれば悪いことではありませんが、気づいていなければ非常に苦痛です
Walt W

プロジェクトは2014年4月の時点で死んでいるように見える
Alojz Janez

7

Vimでは、次の3つのバインディングがあります。

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>

rpdb2リモートPythonデバッガーであり、WinPDB、ソリッドグラフィカルデバッガーで使用できます。私はあなたが尋ねるのを知っているので、それは私がグラフィカルデバッガに行うことを期待するすべてを行うことができます:)

ユニットテストと通常のコードをデバッグできるようにpdbfrom を使用しnose.toolsています。

最後に、F7マッピングはトレースバックを出力します(例外がスタックの一番上にバブルしたときに得られる種類に似ています)。私はそれが数回以上本当に便利だとわかりました。


4

クラスの有用なrepr()メソッドを定義し(オブジェクトが何であるかを確認できるようにする)、repr()または "%r"%(...)または "... {0!r} .."。formatを使用する(...)デバッグメッセージ/ログのIMHOは、効率的なデバッグの鍵です。

また、他の回答で言及されているデバッガーはrepr()メソッドを使用します。


2

実行中のPythonアプリケーションからスタックトレースを取得する

ここにはいくつかのトリックがあります。これらには

  • シグナルを送信してインタープリターに侵入する/スタックトレースを出力する
  • 準備されていないPythonプロセスからスタックトレースを取得する
  • フラグ付きでインタープリターを実行してデバッグに役立てる

2

デバッガーで時間を過ごすのが気に入らない場合(およびpdbコマンドラインインターフェイスの使いやすさが不十分であることに感謝しない場合)は、実行トレースをダンプして後で分析できます。例えば:

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

これにより、setup.py install実行のすべてのソース行がにダンプされexecution.logます。

トレース出力をカスタマイズし、独自のトレーサーを作成しやすくするために、いくつかのコードをxtraceモジュール(パブリックドメイン)にまとめました


1

可能な場合はM-x pdb、ソースレベルのデバッグにemacsを使用してデバッグします。


1

UdacityのAndreas Zellerによる「ソフトウェアデバッグ」と呼ばれる完全なオンラインコースには、デバッグに関するヒントが満載です。

コースの概要

このクラスでは、プログラムを体系的にデバッグする方法、デバッグプロセスを自動化する方法、およびPythonでいくつかの自動デバッグツールを構築する方法を学習します。

このコースを受講する理由

このコースを修了すると、体系的なデバッグについてしっかりと理解し、デバッグを自動化する方法を理解し、Pythonでいくつかの機能的なデバッグツールを構築します。

前提条件と要件

Udacity CS101以上のレベルでのプログラミングとPythonの基本的な知識が必要です。オブジェクト指向プログラミングの基本的な理解は役に立ちます。

強くお勧めします。


0

読みやすい方法でコールスタックを印刷する優れたグラフィカルな方法が必要な場合は、このユーティリティを確認してください。https//github.com/joerick/pyinstrument

コマンドラインから実行:

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

モジュールとして実行:

from pyinstrument import Profiler

profiler = Profiler()
profiler.start()

# code you want to profile

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

ジャンゴで実行:

にを追加pyinstrument.middleware.ProfilerMiddlewareMIDDLEWARE_CLASSES?profileリクエストURLの最後に追加して、プロファイラーをアクティブ化します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.