ログは必須です
何らかのログ設定を行わずにアプリケーションを作成すると、最終的に後悔することになります。アプリケーションにログがないと、エラーのトラブルシューティングが困難になります。幸いなことに、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].baseFilename
Find file path):
[12:52:35] {<stdin>:1} ERROR - Some serious error occurred. [12:52:35] {<stdin>:1} WARNING - Function you are using is deprecated.</stdin></stdin>
このセットアップは (通常の場合と同様) 十分に適切であるように見えますが、構成は適切にフォーマットされています。読みやすいログは作業を楽にしてくれます。構成を改善および拡張する 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></_io>
。
__repr__
に加えて、print(instance)# を呼び出すときにデフォルトで使用される
__str__ メソッドを実装することもお勧めします。 ## 方法。これら 2 つの方法を使用すると、変数を出力するだけで多くの情報を取得できます。
__missing__dictionary の Dunder メソッド
何らかの理由でカスタム辞書クラスを実装する必要がある場合、実際には存在しないキーにアクセスしようとすると、 , KeyErrorによりいくつかのバグが発生する可能性があります。欠落している
key をコード内で探す必要を避けるために、KeyError が発生するたびに呼び出される特別な
__missing__ メソッドを実装できます。
class MyDict(dict): def __missing__(self, key): message = f'{key} not present in the dictionary!' 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.</module>
上面的调试会话非常简单地展示了如何使用pdb
。程序终止后,我们进入交互式调试会话。首先,我们导入pdb
并启动调试器。此时,我们可以使用所有pdb
命令。作为上面的示例,我们使用p
命令打印变量,使用l
命令打印列表代码。大多数情况下,你可能希望设置断点,你可以使用b LINE_NO
来设置断点,并运行程序,直到达到断点(c
),然后继续使用s
单步执行函数,也可以使用w
打印堆栈轨迹。有关命令的完整列表,你可以转到官方pdb文档。
检查堆栈轨迹
例如,假设你的代码是在远程服务器上运行的Flask或Django应用程序,你无法在其中获得交互式调试会话。在这种情况下,你可以使用traceback
和sys
包来了解代码中的错误:
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 サイトの他の関連記事を参照してください。

inpython、youappendelementStoalistusingtheappend()method.1)useappend()forsingleelements:my_list.append(4).2)useextend()or = formultipleElements:my_list.extend(another_list)ormy_list = [4,5,6] .3)forspecificpositions:my_list.insert(1,5).beaware

シェバンの問題をデバッグする方法には次のものがあります。1。シバン行をチェックして、それがスクリプトの最初の行であり、接頭辞スペースがないことを確認します。 2.通訳パスが正しいかどうかを確認します。 3.通訳を直接呼び出してスクリプトを実行して、シェバンの問題を分離します。 4. StraceまたはTrustsを使用して、システムコールを追跡します。 5.シバンに対する環境変数の影響を確認してください。

pythonlistscanbemanipulatedsingseveralmethodstoremoveElements:1)theremove()methodremovesthefirstoccurrenceofaspecifiedValue.2)thepop()methop()methodremovessanelementatagivenindex.3)thedelstatementementementementementementementementementemoritemoricedex.4)

Integers、strings、floats、booleans、otherlists、anddictionaryを含むpythonlistscanstoreanydatype

PythonListsSupportNumersoperations:1)AddingElementSwithAppend()、Extend()、Andinert()

Numpyを使用して多次元配列を作成すると、次の手順を通じて実現できます。1)numpy.array()関数を使用して、np.array([[1,2,3]、[4,5,6]])などの配列を作成して2D配列を作成します。 2)np.zeros()、np.ones()、np.random.random()およびその他の関数を使用して、特定の値で満たされた配列を作成します。 3)アレイの形状とサイズの特性を理解して、サブアレイの長さが一貫していることを確認し、エラーを回避します。 4)np.reshape()関数を使用して、配列の形状を変更します。 5)コードが明確で効率的であることを確認するために、メモリの使用に注意してください。

BroadcastinginNumPyisamethodtoperformoperationsonarraysofdifferentshapesbyautomaticallyaligningthem.Itsimplifiescode,enhancesreadability,andboostsperformance.Here'showitworks:1)Smallerarraysarepaddedwithonestomatchdimensions.2)Compatibledimensionsare

Forpythondatastorage、chooseLists forfficability withmixeddatypes、array.arrayformemory-efficienthogeneousnumericaldata、およびnumpyArrays foradvancednumericalcomputing.listSareversatilebuteficient efficient forlargeNumericaldatates;


ホットAIツール

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

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

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

AtomエディタMac版ダウンロード
最も人気のあるオープンソースエディター

EditPlus 中国語クラック版
サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません

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

Safe Exam Browser
Safe Exam Browser は、オンライン試験を安全に受験するための安全なブラウザ環境です。このソフトウェアは、あらゆるコンピュータを安全なワークステーションに変えます。あらゆるユーティリティへのアクセスを制御し、学生が無許可のリソースを使用するのを防ぎます。

SAP NetWeaver Server Adapter for Eclipse
Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

ホットトピック









