PyLintメッセージ:logging-format-interpolation


161

次のコードの場合:

logger.debug('message: {}'.format('test'))

pylint 次の警告が生成されます。

ロギングフォーマット補間(W1202):

ロギング関数で%フォーマットを使用して、引数として%パラメーターを渡します。ロギングステートメントに「logging。(format_string.format(format_args ...))」の呼び出し形式がある場合に使用されます。そのような呼び出しでは、代わりに%形式を使用する必要がありますが、引数としてパラメーターを渡すことにより、ログ関数に補間を残します。

この警告をオフにできることはわかっていますが、理解したいと思います。format()Python 3でステートメントを出力する方法として、を使用するのが望ましいと思いました。ロガーステートメントにこれが当てはまらないのはなぜですか?

回答:


203

これは、ロガー呼び出しに渡される追加の引数を使用してこの文字列の遅延補間を提供するために、文字列のような以前の「%」形式に依存しているため、ロガーステートメントには当てはまりません。たとえば、代わりに:

logger.error('oops caused by %s' % exc)

やったほうがいい

logger.error('oops caused by %s', exc)

そのため、メッセージが実際に発行された場合にのみ文字列が補間されます。

を使用して.format()いる場合は、この機能を利用できません。


あたりの最適化のセクションloggingドキュメント:

メッセージ引数のフォーマットは、回避できなくなるまで延期されます。ただし、loggingメソッドに渡された引数を計算することも負荷が高くなる可能性があり、ロガーがイベントを破棄するだけの場合は、それを避けたい場合があります。


4
@ pfnuesel、.format()は、logger.errorの呼び出し前に展開されますが、「遅延補間」は、必要な場合にのみ展開が行われることを意味します(たとえば、メッセージは実際にどこかに表示されます)
sthenault

10
この遅延評価が優先され、違いを生むための優れたリファレンスはありますか?PEP282ロギングライブラリ
culix

25
しかし、これは後でコードのメンテナンス問題が発生することを意味するだけですか?アップグレードした.format()ので、ある時点でスタイルに移行するために、pylintによって後で「推奨」さloggingれますか?少なくともほとんどのタスクで、最先端の速度パフォーマンスよりも保守性に関心があるので、質問します。
マイクウィリアムソン

3
@MikeWilliamson:副作用の可能性があるため、このメッセージは警告だと思いますが、無視しても問題ありません。
saihtamtellim

5
警告の背後にある動機の多くはパフォーマンスに関するものです(つまり、ログステートメントが発行されない場合は、補間コストが節約されます)が、多くの(おそらくほとんどの)アプリケーションではパフォーマンスコストは無視できるほどです。参照:github.com/PyCQA/pylint/issues/2395およびgithub.com/PyCQA/pylint/issues/2354
Adam Parkin

23

たぶん、この時間差が役立つかもしれません。

次の説明はあなたの質問に対する答えではありませんが、人々を助けることができます。

pylint 2.4の場合:でスタイルを記録するための3つのオプションがあり.pylintrcます。ファイルはoldnewfstr

fstr2.4で追加され、2.5で削除されたオプション

.pylintrcファイルからの説明(v2.4):

[LOGGING]

# Format style used to check logging format string. `old` means using %
# formatting, `new` is for `{}` formatting,and `fstr` is for f-strings.
logging-format-style=old

以下のための古いですlogging-format-style=old):

foo = "bar"
self.logger.info("foo: %s", foo)

以下のための新しいですlogging-format-style=new):

foo = "bar"
self.logger.info("foo: {}", foo)
# OR
self.logger.info("foo: {foo}", foo=foo)

:オプションを選択しても使用できません.format()new

pylint はこのコードに対しても同じ警告出します:

self.logger.info("foo: {}".format(foo))  # W1202
# OR
self.logger.info("foo: {foo}".format(foo=foo))  # W1202

FSTRlogging-format-style=fstr):

foo = "bar"
self.logger.info(f"foo: {foo}")

個人的に、私はPEP-0498のためにfstrオプションを好みます。


2
"python.linting.pylintArgs": ["--logging-format-style=old"]vscode / settings.jsonファイルに追加できます。docs
mustafagok

2
pylint 2.3.1で:optparse.OptionValueError: option logging-format-style: invalid value: 'fstr', should be in ['old', 'new']最新のpylint(2.4.4)にアップグレードすると、これが修正されました。
フロリアンカステラーヌ

私は、次のようなエラーが生じています:Try installing a more recent version of python-pylint, and please open a bug report if the issue persists in t\ he latest release. Thanks!
アルパース

3

私の経験では、遅延補間の最適化(ほとんどのユースケースの場合)よりも説得力のある理由は、Sentryのようなログアグリゲーターでうまく機能するためです。

「ユーザーがログインしました」というログメッセージについて考えてみます。ユーザーをフォーマット文字列に挿入すると、ユーザーの数と同じ数の個別のログメッセージが表示されます。このような遅延補間を使用する場合、ログアグリゲーターは、これをより多くの異なるインスタンスを持つ同じログメッセージとしてより合理的に解釈できます。

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