PyLint-Nachricht: Protokollierungsformat-Interpolation


161

Für den folgenden Code:

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

pylint erzeugt die folgende Warnung:

Protokollierungsformat-Interpolation (W1202):

Verwenden Sie die% -Formatierung in Protokollierungsfunktionen und übergeben Sie die% -Parameter als Argumente. Wird verwendet, wenn eine Protokollierungsanweisung die Aufrufform "Protokollierung. (Format_string.format (format_args ...))" hat. Solche Aufrufe sollten stattdessen die% -Formatierung verwenden, aber die Interpolation der Protokollierungsfunktion überlassen, indem die Parameter als Argumente übergeben werden.

Ich weiß, dass ich diese Warnung ausschalten kann, aber ich würde sie gerne verstehen. Ich nahm an, dass die Verwendung format()der bevorzugten Methode zum Ausdrucken von Anweisungen in Python 3 ist. Warum gilt dies nicht für Logger-Anweisungen?

Antworten:


203

Dies gilt nicht für die Logger-Anweisung, da sie sich auf das frühere "%" -Format wie eine Zeichenfolge stützt, um eine verzögerte Interpolation dieser Zeichenfolge mithilfe zusätzlicher Argumente für den Logger-Aufruf zu ermöglichen. Zum Beispiel anstatt zu tun:

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

du solltest tun

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

Daher wird die Zeichenfolge nur interpoliert, wenn die Nachricht tatsächlich ausgegeben wird.

Sie können diese Funktionalität bei der Verwendung nicht nutzen .format().


Gemäß dem Abschnitt " Optimierung " der loggingDokumente:

Die Formatierung von Nachrichtenargumenten wird verschoben, bis sie nicht mehr vermieden werden kann. Das Berechnen der an die Protokollierungsmethode übergebenen Argumente kann jedoch auch teuer sein, und Sie möchten dies möglicherweise vermeiden, wenn der Protokollierer Ihr Ereignis einfach wegwirft.


4
@pfnuesel, .format () wird vor dem Aufruf von logger.error erweitert, während "Lazy Interpolation" bedeutet, dass die Erweiterung nur bei Bedarf erfolgt (z. B. wird die Nachricht tatsächlich irgendwo angezeigt)
sthenault

10
Gibt es eine gute Referenz dafür, dass diese faule Bewertung bevorzugt wird und einen Unterschied macht? Ich konnte keine in PEP282 oder der Protokollierungsbibliothek finden
culix

25
Aber bedeutet dies nur, dass wir später Wartungsprobleme mit unserem Code haben werden? Werden wir später von Pylint "empfohlen", irgendwann zum .format()Stil zu wechseln, weil er loggingaktualisiert wurde? Ich frage, weil ich mehr an Wartbarkeit interessiert bin als an der neuesten Geschwindigkeitsleistung, zumindest für die meisten Aufgaben.
Mike Williamson

3
@ MikeWilliamson: Ich denke, diese Nachricht ist eine Warnung, da es mögliche Nebenwirkungen gibt, aber Sie können sie sicher ignorieren.
Saihtamtellim

5
Während ein Großteil der Motivation hinter der Warnung in der Leistung liegt (dh wenn keine Protokollanweisung ausgegeben wird, werden die Interpolationskosten eingespart), ist anzumerken, dass in vielen (wohl den meisten) Anwendungen die Leistungskosten vernachlässigbar sind. Siehe: github.com/PyCQA/pylint/issues/2395 und github.com/PyCQA/pylint/issues/2354
Adam Parkin

23

Vielleicht können Ihnen diesmal Zeitunterschiede helfen.

Die folgende Beschreibung ist nicht die Antwort auf Ihre Frage, kann aber Menschen helfen.

Für Pylint 2.4: Es gibt drei Optionen für Stil in der Logging - .pylintrcDatei: old, new,fstr

fstrOption in 2.4 hinzugefügt und in 2.5 entfernt

Beschreibung aus .pylintrcDatei (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

für alt ( logging-format-style=old):

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

für new ( logging-format-style=new):

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

Hinweis : Sie können nicht verwenden, .format()auch wenn Sie auswählennew Option .

pylint gibt immer noch die gleiche Warnung für diesen Code aus:

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

für fstr ( logging-format-style=fstr):

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

Persönlich bevorzuge ich die Option fstr wegen PEP-0498 .


2
Sie können "python.linting.pylintArgs": ["--logging-format-style=old"]der Datei vscode / settings.json hinzufügen . docs
mustafagok

2
in pylint 2.3.1: Das optparse.OptionValueError: option logging-format-style: invalid value: 'fstr', should be in ['old', 'new']Upgrade auf das neueste pylint (2.4.4) hat dies behoben.
Florian Castellane

Ich habe folgenden Fehler: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!
Alper

3

Nach meiner Erfahrung ist ein überzeugenderer Grund als die Optimierung (für die meisten Anwendungsfälle) für die verzögerte Interpolation, dass sie gut mit Protokollaggregatoren wie Sentry funktioniert.

Betrachten Sie eine Protokollmeldung "Benutzer angemeldet". Wenn Sie den Benutzer in die Formatzeichenfolge interpolieren, haben Sie so viele unterschiedliche Protokollnachrichten, wie Benutzer vorhanden sind. Wenn Sie eine verzögerte Interpolation wie diese verwenden, kann der Protokollaggregator dies vernünftigerweise als dieselbe Protokollnachricht mit einer Reihe verschiedener Instanzen interpretieren.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.