目次
ログは必須です
ログ デコレーター
__missing__dictionary の Dunder メソッド
调试崩溃的应用程序
检查堆栈轨迹
在调试期间重新加载模块
ホームページ バックエンド開発 Python チュートリアル Pythonでデバッグする方法は何ですか?

Pythonでデバッグする方法は何ですか?

May 12, 2023 pm 08:13 PM
python

ログは必須です

何らかのログ設定を行わずにアプリケーションを作成すると、最終的に後悔することになります。アプリケーションにログがないと、エラーのトラブルシューティングが困難になります。幸いなことに、Python では、基本的なロガーのセットアップは非常に簡単です。

import logging
logging.basicConfig(
    filename='application.log',
    level=logging.WARNING,
    format= '[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s',
    datefmt='%H:%M:%S'
)

logging.error("Some serious error occurred.")
logging.warning('Function you are using is deprecated.')
ログイン後にコピー

これだけでファイルへのログの書き込みを開始できます。ファイルは次のようになります (logging.getLoggerClass() を使用できます) .root.handlers[0].baseFilenameFind file path):

[12:52:35] {<stdin>:1} ERROR - Some serious error occurred.
[12:52:35] {<stdin>:1} WARNING - Function you are using is deprecated.
ログイン後にコピー

このセットアップは (通常の場合と同様) 十分に適切であるように見えますが、構成は適切にフォーマットされています。読みやすいログは作業を楽にしてくれます。構成を改善および拡張する 1 つの方法は、ロガーが読み取る .ini または .yaml ファイルを使用することです。たとえば、構成で次のことを実行できます。

version: 1
disable_existing_loggers: true

formatters:
  standard:
    format: "[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s"
    datefmt: '%H:%M:%S'

handlers:
  console:  # handler which will log into stdout
    class: logging.StreamHandler
    level: DEBUG
    formatter: standard  # Use formatter defined above
    stream: ext://sys.stdout
  file:  # handler which will log into file
    class: logging.handlers.RotatingFileHandler
    level: WARNING
    formatter: standard  # Use formatter defined above
    filename: /tmp/warnings.log
    maxBytes: 10485760 # 10MB
    backupCount: 10
    encoding: utf8

root:  # Loggers are organized in hierarchy - this is the root logger config
  level: ERROR
  handlers: [console, file]  # Attaches both handler defined above

loggers:  # Defines descendants of root logger
  mymodule:  # Logger for "mymodule"
    level: INFO
    handlers: [file]  # Will only use "file" handler defined above
    propagate: no  # Will not propagate logs to "root" logger
ログイン後にコピー

この種の広範な構成を Python コードに含めると、移動、編集、および保守が困難になります。コンテンツを YAML ファイルに保存すると、上記のような非常に具体的な設定を使用して複数のロガーをセットアップおよび調整することが簡単になります。

これらの設定フィールドがどこから来たのか疑問に思っている場合は、これらは公式ドキュメントに記載されており、最初の例に示すように、そのほとんどは単なる キーワード パラメーターです。

これで、ファイルに設定ができました。つまり、それを何らかの方法でロードする必要があります。最も簡単な方法は、YAML ファイルを使用することです。

import yaml
from logging import config

with open("config.yaml", 'rt') as f:
    config_data = yaml.safe_load(f.read())
    config.dictConfig(config_data)
ログイン後にコピー

Python ロガーは、実際には YAML ファイルを直接サポートしませんが、dictionary 構成をサポートします。これは、yaml を使用して実行できます。 .safe_load YAML から辞書構成を簡単に作成します。古い .ini ファイルを使用したい場合は、公式ドキュメントによると、新しいアプリケーションには辞書構成を使用することが推奨されるアプローチであることを指摘しておきます。その他の例については、公式のログ記録マニュアルを参照してください。

ログ デコレーター

前のログ手法を続けると、エラー関数呼び出しを記録する必要がある場合があります。前記関数の本体を変更する代わりに、特定のログ レベルとオプションのメッセージを使用して各関数呼び出しをログに記録するログ デコレーターを使用できます。デコレータを見てみましょう:

from functools import wraps, partial
import logging

def attach_wrapper(obj, func=None):  # Helper function that attaches function as attribute of an object
    if func is None:
        return partial(attach_wrapper, obj)
    setattr(obj, func.__name__, func)
    return func

def log(level, message):  # Actual decorator
    def decorate(func):
        logger = logging.getLogger(func.__module__)  # Setup logger
        formatter = logging.Formatter(
            '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        handler = logging.StreamHandler()
        handler.setFormatter(formatter)
        logger.addHandler(handler)
        log_message = f"{func.__name__} - {message}"

        @wraps(func)
        def wrapper(*args, **kwargs):  # Logs the message and before executing the decorated function
            logger.log(level, log_message)
            return func(*args, **kwargs)

        @attach_wrapper(wrapper)  # Attaches "set_level" to "wrapper" as attribute
        def set_level(new_level):  # Function that allows us to set log level
            nonlocal level
            level = new_level

        @attach_wrapper(wrapper)  # Attaches "set_message" to "wrapper" as attribute
        def set_message(new_message):  # Function that allows us to set message
            nonlocal log_message
            log_message = f"{func.__name__} - {new_message}"

        return wrapper
    return decorate

# Example Usage
@log(logging.WARN, "example-param")
def somefunc(args):
    return args

somefunc("some args")

somefunc.set_level(logging.CRITICAL)  # Change log level by accessing internal decorator function
somefunc.set_message("new-message")  # Change log message by accessing internal decorator function
somefunc("some args")
ログイン後にコピー

言うまでもなく、これを理解するのに少し時間がかかるかもしれません (コピーアンドペーストして使用するだけでもよいでしょう)。ここでの考え方は、log 関数が引数を受け取り、それを内部の wrapper 関数に提供するということです。次に、デコレーターにアタッチされたアクセサー関数を追加して、これらのパラメーターを調整できるようにします。 functools.wraps デコレータについては、ここで使用しない場合、関数の名前 (func.__name__) がデコレータの名前で上書きされます。しかし、名前を印刷したいので、これは問題です。これは、functools.wraps関数名、docstring、および引数リストをデコレータ関数にコピーすることで解決できます。

とにかく、これは上記のコードの出力です。かなりきれいですよね?

2020-05-01 14:42:10,289 - __main__ - WARNING - somefunc - example-param
2020-05-01 14:42:10,289 - __main__ - CRITICAL - somefunc - new-message
ログイン後にコピー

__repr__より読みやすいログ

デバッグを容易にするためにコードを簡単に改善するには、クラスに __repr__ メソッドを追加します。 。このメソッドに慣れていない場合は、クラス インスタンスの文字列表現を返すだけです。 __repr__ メソッドのベスト プラクティスは、インスタンスの再作成に使用できるテキストを出力することです。例:

class Circle:
    def __init__(self, x, y, radius):
        self.x = x
        self.y = y
        self.radius = radius

    def __repr__(self):
        return f"Rectangle({self.x}, {self.y}, {self.radius})"

...
c = Circle(100, 80, 30)
repr(c)
# Circle(100, 80, 30)
ログイン後にコピー

上記のようにオブジェクトが望ましくない、または不可能な場合、代わりに <...> (例: <_io) を使用することをお勧めします。 .TextIOWrapper 名='somefile.txt' モード='w' エンコーディング='UTF-8'>

__repr__ に加えて、print(instance)# を呼び出すときにデフォルトで使用される __str__ メソッドを実装することもお勧めします。 ## 方法。これら 2 つの方法を使用すると、変数を出力するだけで多くの情報を取得できます。

__missing__dictionary の Dunder メソッド

何らかの理由でカスタム辞書クラスを実装する必要がある場合、実際には存在しないキーにアクセスしようとすると、 ,

KeyErrorによりいくつかのバグが発生する可能性があります。欠落している key をコード内で探す必要を避けるために、KeyError が発生するたびに呼び出される特別な __missing__ メソッドを実装できます。

class MyDict(dict):
    def __missing__(self, key):
        message = f&#39;{key} not present in the dictionary!&#39;
        logging.warning(message)
        return message  # Or raise some error instead
ログイン後にコピー

上記の実装は非常に単純で、欠落している

key を含むメッセージを返してログに記録するだけですが、コード内のエラーに関する情報を提供するために、他の貴重な情報をログに記録することもできます。より多くのコンテキスト。

调试崩溃的应用程序

如果你的应用程序在你有机会看到其中发生了什么之前崩溃,你可能会发现这个技巧非常有用。

-i使用参数-i ( python3 -i app.py)运行应用程序会导致它在程序退出后立即启动交互式 shell。此时你可以检查变量和函数。

如果这还不够好,可以使用更大的hammer-pdb-Python调试器。pdb有相当多的特性,可以保证文章的独立性。但这里是一个例子和最重要的部分概要。让我们先看看我们的小崩溃脚本:

# crashing_app.py
SOME_VAR = 42

class SomeError(Exception):
    pass

def func():
    raise SomeError("Something went wrong...")

func()
ログイン後にコピー

现在,如果我们使用-i参数运行它,我们就有机会调试它:

# Run crashing application
~ $ python3 -i crashing_app.py
Traceback (most recent call last):
  File "crashing_app.py", line 9, in <module>
    func()
  File "crashing_app.py", line 7, in func
    raise SomeError("Something went wrong...")
__main__.SomeError: Something went wrong...
>>> # We are interactive shell
>>> import pdb
>>> pdb.pm()  # start Post-Mortem debugger
> .../crashing_app.py(7)func()
-> raise SomeError("Something went wrong...")
(Pdb) # Now we are in debugger and can poke around and run some commands:
(Pdb) p SOME_VAR  # Print value of variable
42
(Pdb) l  # List surrounding code we are working with
  2
  3   class SomeError(Exception):
  4       pass
  5
  6   def func():
  7  ->     raise SomeError("Something went wrong...")
  8
  9   func()
[EOF]
(Pdb)  # Continue debugging... set breakpoints, step through the code, etc.<p data-id="p838747a-jbmZAH6B">上面的调试会话非常简单地展示了如何使用<code>pdb</code>。程序终止后,我们进入交互式调试会话。首先,我们导入<code>pdb</code>并启动调试器。此时,我们可以使用所有<code>pdb</code>命令。作为上面的示例,我们使用<code>p</code>命令打印变量,使用<code>l</code>命令打印列表代码。大多数情况下,你可能希望设置断点,你可以使用<code>b LINE_NO</code>来设置断点,并运行程序,直到达到断点(<code>c</code>),然后继续使用<code>s</code>单步执行函数,也可以使用<code>w</code>打印堆栈轨迹。有关命令的完整列表,你可以转到官方pdb文档。</p>
<h3 id="检查堆栈轨迹">检查堆栈轨迹</h3>
<p data-id="p124945a-Ln9Ti0YE">例如,假设你的代码是在远程服务器上运行的Flask或Django应用程序,你无法在其中获得交互式调试会话。在这种情况下,你可以使用<code>traceback</code>和<code>sys</code>包来了解代码中的错误:</p>
<pre class="brush:php;toolbar:false">import traceback
import sys

def func():
    try:
        raise SomeError("Something went wrong...")
    except:
        traceback.print_exc(file=sys.stderr)
ログイン後にコピー

运行时,上面的代码将打印引发的最后一个异常。除了打印例外,你还可以使用traceback包打印堆栈轨迹(traceback.print_stack())或提取原始堆栈帧,对其进行格式化并进一步检查(traceback.format_list(traceback.extract_stack()))。

在调试期间重新加载模块

有时,你可能正在调试或试验交互式shell中的某些函数,并对其进行频繁更改。为了使运行/测试和修改的循环更容易,你可以运行importlib.reload(module)以避免每次更改后重新启动交互会话:

>>> import func from module
>>> func()
"This is result..."

# Make some changes to "func"
>>> func()
"This is result..."  # Outdated result
>>> from importlib import reload; reload(module)  # Reload "module" after changes made to "func"
>>> func()
"New result..."
ログイン後にコピー

这个技巧更多的是关于效率而不是调试。能够跳过一些不必要的步骤,使你的工作流程更快、更高效,这总是很好的。通常,不时地重新加载模块是一个好主意,因为它可以帮助你避免调试同时已经修改过多次的代码。

以上がPythonでデバッグする方法は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

PHPおよびPython:コードの例と比較 PHPおよびPython:コードの例と比較 Apr 15, 2025 am 12:07 AM

PHPとPythonには独自の利点と短所があり、選択はプロジェクトのニーズと個人的な好みに依存します。 1.PHPは、大規模なWebアプリケーションの迅速な開発とメンテナンスに適しています。 2。Pythonは、データサイエンスと機械学習の分野を支配しています。

Python vs. JavaScript:コミュニティ、ライブラリ、リソース Python vs. JavaScript:コミュニティ、ライブラリ、リソース Apr 15, 2025 am 12:16 AM

PythonとJavaScriptには、コミュニティ、ライブラリ、リソースの観点から、独自の利点と短所があります。 1)Pythonコミュニティはフレンドリーで初心者に適していますが、フロントエンドの開発リソースはJavaScriptほど豊富ではありません。 2)Pythonはデータサイエンスおよび機械学習ライブラリで強力ですが、JavaScriptはフロントエンド開発ライブラリとフレームワークで優れています。 3)どちらも豊富な学習リソースを持っていますが、Pythonは公式文書から始めるのに適していますが、JavaScriptはMDNWebDocsにより優れています。選択は、プロジェクトのニーズと個人的な関心に基づいている必要があります。

CentosのPytorchのGPUサポートはどのようにサポートされていますか CentosのPytorchのGPUサポートはどのようにサポートされていますか Apr 14, 2025 pm 06:48 PM

Pytorch GPUアクセラレーションを有効にすることで、CentOSシステムでは、PytorchのCUDA、CUDNN、およびGPUバージョンのインストールが必要です。次の手順では、プロセスをガイドします。CUDAおよびCUDNNのインストールでは、CUDAバージョンの互換性が決定されます。NVIDIA-SMIコマンドを使用して、NVIDIAグラフィックスカードでサポートされているCUDAバージョンを表示します。たとえば、MX450グラフィックカードはCUDA11.1以上をサポートする場合があります。 cudatoolkitのダウンロードとインストール:nvidiacudatoolkitの公式Webサイトにアクセスし、グラフィックカードでサポートされている最高のCUDAバージョンに従って、対応するバージョンをダウンロードしてインストールします。 cudnnライブラリをインストールする:

Dockerの原則の詳細な説明 Dockerの原則の詳細な説明 Apr 14, 2025 pm 11:57 PM

DockerはLinuxカーネル機能を使用して、効率的で孤立したアプリケーションランニング環境を提供します。その作業原則は次のとおりです。1。ミラーは、アプリケーションを実行するために必要なすべてを含む読み取り専用テンプレートとして使用されます。 2。ユニオンファイルシステム(UnionFS)は、違いを保存するだけで、スペースを節約し、高速化する複数のファイルシステムをスタックします。 3.デーモンはミラーとコンテナを管理し、クライアントはそれらをインタラクションに使用します。 4。名前空間とcgroupsは、コンテナの分離とリソースの制限を実装します。 5.複数のネットワークモードは、コンテナの相互接続をサポートします。これらのコア概念を理解することによってのみ、Dockerをよりよく利用できます。

ミニオペンCentosの互換性 ミニオペンCentosの互換性 Apr 14, 2025 pm 05:45 PM

MINIOオブジェクトストレージ:CENTOSシステムの下での高性能展開Minioは、Amazons3と互換性のあるGO言語に基づいて開発された高性能の分散オブジェクトストレージシステムです。 Java、Python、JavaScript、Goなど、さまざまなクライアント言語をサポートしています。この記事では、CentosシステムへのMinioのインストールと互換性を簡単に紹介します。 Centosバージョンの互換性Minioは、Centos7.9を含むがこれらに限定されない複数のCentosバージョンで検証されています。

CentosでPytorchの分散トレーニングを操作する方法 CentosでPytorchの分散トレーニングを操作する方法 Apr 14, 2025 pm 06:36 PM

Pytorchの分散トレーニングでは、Centosシステムでトレーニングには次の手順が必要です。Pytorchのインストール:PythonとPipがCentosシステムにインストールされていることです。 CUDAバージョンに応じて、Pytorchの公式Webサイトから適切なインストールコマンドを入手してください。 CPUのみのトレーニングには、次のコマンドを使用できます。PipinstalltorchtorchtorchvisionTorchaudioGPUサポートが必要な場合は、CUDAとCUDNNの対応するバージョンがインストールされ、インストールに対応するPytorchバージョンを使用してください。分散環境構成:分散トレーニングには、通常、複数のマシンまたは単一マシンの複数GPUが必要です。場所

CentosでPytorchバージョンを選択する方法 CentosでPytorchバージョンを選択する方法 Apr 14, 2025 pm 06:51 PM

PytorchをCentosシステムにインストールする場合、適切なバージョンを慎重に選択し、次の重要な要因を検討する必要があります。1。システム環境互換性:オペレーティングシステム:Centos7以上を使用することをお勧めします。 Cuda and Cudnn:PytorchバージョンとCudaバージョンは密接に関連しています。たとえば、pytorch1.9.0にはcuda11.1が必要ですが、pytorch2.0.1にはcuda11.3が必要です。 CUDNNバージョンは、CUDAバージョンとも一致する必要があります。 Pytorchバージョンを選択する前に、互換性のあるCUDAおよびCUDNNバージョンがインストールされていることを確認してください。 Pythonバージョン:Pytorch公式支店

Python:自動化、スクリプト、およびタスク管理 Python:自動化、スクリプト、およびタスク管理 Apr 16, 2025 am 12:14 AM

Pythonは、自動化、スクリプト、およびタスク管理に優れています。 1)自動化:OSやShutilなどの標準ライブラリを介してファイルバックアップが実現されます。 2)スクリプトの書き込み:Psutilライブラリを使用してシステムリソースを監視します。 3)タスク管理:スケジュールライブラリを使用してタスクをスケジュールします。 Pythonの使いやすさと豊富なライブラリサポートにより、これらの分野で優先ツールになります。

See all articles