PyLint消息:日志记录格式插值


161

对于以下代码:

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

pylint 产生以下警告:

日志记录格式插值(W1202):

在日志记录函数中使用%格式,并将%参数作为参数传递。在日志记录语句的调用形式为“ logging。(format_string.format(format_args ...))”时使用。此类调用应改为使用%格式,但通过将参数作为参数传递,将插值留给日志记录函数。

我知道我可以关闭此警告,但我想理解它。我假定使用format()是在Python 3中打印语句的首选方法。为什么这对于logger语句不是正确的?

Answers:


203

logger语句不是正确的,因为它依赖于以前的“%”格式(例如字符串)来使用给logger调用提供的额外参数来对该字符串进行延迟插值。例如,而不是做:

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

你应该做

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

因此,仅当实际发出消息时才对字符串进行插值。

使用时,您将无法利用此功能.format()


根据文档的“ 优化”部分logging

消息参数的格式将推迟到无法避免为止。但是,计算传递给日志记录方法的参数也可能很昂贵,并且如果记录器将只是丢弃您的事件,则可能要避免这样做。


4
@pfnuesel,.format()在调用logger.error之前被扩展,而“惰性插值”意味着仅在需要时才进行扩展(例如,消息实际上显示在某处)
sthenault

10
对于这种懒惰的评估是否值得推荐并有所作为,有很好的参考吗?我在PEP282日志记录库中
culix '16

25
但这是否意味着以后我们的代码会有维护问题?pylint会不会在以后.format()某个时候因为logging升级而将其“推荐”到该样式?我之所以这样问,是因为我对可维护性的兴趣比对最前沿的速度性能更感兴趣,至少对于大多数任务而言。
Mike Williamson

3
@MikeWilliamson:我认为此消息是警告,因为可能会有副作用,但是您可以放心地忽略它。
saihtamtellim '18

5
虽然警告背后的动机大多与性能有关(即:如果未发出日志语句,则可以节省插值成本),但值得注意的是,在许多(可以说是大多数)应用程序中,性能成本可以忽略不计。参见:github.com/PyCQA/pylint/issues/2395github.com/PyCQA/pylint/issues/2354
亚当·帕金

23

也许这段时间的差异可以帮助您。

以下描述不是您问题的答案,但可以帮助人们。

对于pylint的2.4:对于中记录样式3个选择.pylintrc文件:oldnewfstr

fstr选项在2.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)修复了此问题。
Florian Castellane

我遇到以下错误: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

以我的经验,对于惰性插值而言,比优化(对于大多数用例)更令人信服的原因是,它与Sentry之类的日志聚合器配合得很好。

考虑“用户已登录”日志消息。如果将用户插值到格式字符串中,则与用户一样多的不同日志消息。如果您像这样使用惰性插值,则日志聚合器可以更合理地将其解释为具有多个不同实例的同一条日志消息。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.