Pesan PyLint: logging-format-interpolasi

161

Untuk kode berikut:

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

pylint menghasilkan peringatan berikut:

logging-format-interpolasi (W1202):

Gunakan% pemformatan dalam fungsi logging dan berikan parameter% sebagai argumen Digunakan ketika pernyataan logging memiliki bentuk panggilan "logging. (Format_string.format (format_args ...))". Panggilan seperti itu harus menggunakan format% sebagai gantinya, tetapi meninggalkan interpolasi ke fungsi logging dengan meneruskan parameter sebagai argumen.

Saya tahu saya bisa mematikan peringatan ini, tetapi saya ingin memahaminya. Saya berasumsi menggunakan format()adalah cara yang disukai untuk mencetak pernyataan dengan Python 3. Mengapa ini tidak benar untuk pernyataan logger?

pnuesel
sumber

Jawaban:

204

Itu tidak benar untuk pernyataan logger karena bergantung pada format "%" seperti string untuk menyediakan interpolasi malas string ini menggunakan argumen tambahan yang diberikan kepada panggilan logger. Misalnya alih-alih melakukan:

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

kamu seharusnya melakukan

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

jadi string hanya akan diinterpolasi jika pesan benar-benar dipancarkan.

Anda tidak dapat memanfaatkan fungsi ini saat menggunakan .format().


Per Optimasi bagian dari loggingdocs:

Pemformatan argumen pesan ditangguhkan hingga tidak dapat dihindari. Namun, menghitung argumen yang diteruskan ke metode logging juga bisa mahal, dan Anda mungkin ingin menghindari melakukannya jika logger hanya akan membuang acara Anda.

sthenault
sumber
4
@ pfnuesel, .format () diperluas sebelum panggilan ke logger.error, sementara "interpolasi malas" berarti ekspansi dilakukan hanya jika diperlukan (mis. pesan tersebut benar-benar ditampilkan di suatu tempat)
sthenault
10
Apakah ada referensi yang baik untuk evaluasi malas ini yang lebih disukai dan membuat perbedaan? Saya tidak dapat menemukan satu di PEP282 atau perpustakaan logging
culix
25
Tetapi apakah ini hanya berarti bahwa kita akan memiliki masalah pemeliharaan dengan kode kita nanti? Akankah kita nanti "direkomendasikan" oleh pylint untuk pindah ke .format()gaya di beberapa titik karena loggingtelah ditingkatkan? Saya bertanya karena saya lebih tertarik pada kemampuan pemeliharaan daripada kinerja kecepatan yang tinggi, setidaknya untuk sebagian besar tugas.
Mike Williamson
3
@ MikeWilliamson: Saya pikir pesan ini peringatan karena ada kemungkinan efek samping, tetapi Anda dapat dengan aman mengabaikannya.
saihtamtellim
5
Sementara sebagian besar motivasi di balik peringatan itu adalah kinerja (yaitu: jika pernyataan log tidak dikeluarkan, maka biaya interpolasi dihemat), perlu dicatat bahwa dalam banyak aplikasi (bisa dibilang sebagian besar) biaya kinerja dapat diabaikan. Lihat: github.com/PyCQA/pylint/issues/2395 dan github.com/PyCQA/pylint/issues/2354
Adam Parkin
23

Mungkin perbedaan kali ini dapat membantu Anda.

Deskripsi berikut bukan jawaban untuk pertanyaan Anda, tetapi dapat membantu orang.

Untuk pylint 2.4: Ada 3 pilihan untuk gaya logging di .pylintrcberkas: old, new,fstr

fstropsi ditambahkan pada 2.4 dan dihapus pada 2.5

Deskripsi dari .pylintrcfile (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

untuk yang lama ( logging-format-style=old):

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

untuk baru ( logging-format-style=new):

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

Catatan : Anda tidak dapat menggunakan .format()bahkan jika Anda memilih newopsi.

pylint masih memberikan peringatan yang sama untuk kode ini:

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

untuk fstr ( logging-format-style=fstr):

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

Secara pribadi, saya lebih suka opsi fstr karena PEP-0498 .

mustafagok
sumber
2
Anda dapat menambahkan "python.linting.pylintArgs": ["--logging-format-style=old"]ke file vscode / settings.json. docs
mustafagok
2
di pylint 2.3.1: optparse.OptionValueError: option logging-format-style: invalid value: 'fstr', should be in ['old', 'new']memutakhirkan ke pylint terbaru (2.4.4) memperbaikinya.
Florian Castellane
Saya mengalami kesalahan berikut: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
4

Dalam pengalaman saya, alasan yang lebih menarik daripada optimasi (untuk kebanyakan kasus penggunaan) untuk interpolasi yang malas adalah karena ia berfungsi dengan baik dengan agregator log seperti Sentry.

Pertimbangkan pesan log 'pengguna masuk'. Jika Anda menginterpolasi pengguna ke dalam format string, Anda memiliki banyak pesan log berbeda seperti halnya ada pengguna. Jika Anda menggunakan interpolasi malas seperti ini, agregator log dapat lebih menafsirkan ini sebagai pesan log yang sama dengan banyak contoh berbeda.

Tristan Crockett
sumber