字符串格式:%vs. .format与F-string字面
有各种字符串格式方法:
- Python< 2.6:
“ Hello%S”%name
- Python 2.6+:
“ Hello {}”。格式(name)
  (使用str.format.format
)
- Python 3.6+:
f“ {name}”
  (使用f-strings)
哪个更好,在什么情况下?
以下方法具有相同的结果,那么差异是什么?
name =“ Alice” “ Hello%S”%名称 “你好{0}”。格式(名称) f“你好{name}” #使用命名参数: “ Hello%(Kwarg)S”%{'Kwarg':name} “你好{kwarg}”。格式(kwarg = name) f“你好{name}”
字符串格式何时运行,如何避免运行时性能罚款?
There are various string formatting methods:
- Python <2.6:
"Hello %s" % name
- Python 2.6+:
"Hello {}".format(name)
(usesstr.format
) - Python 3.6+:
f"{name}"
(uses f-strings)
Which is better, and for what situations?
The following methods have the same outcome, so what is the difference?
name = "Alice" "Hello %s" % name "Hello {0}".format(name) f"Hello {name}" # Using named arguments: "Hello %(kwarg)s" % {'kwarg': name} "Hello {kwarg}".format(kwarg=name) f"Hello {name}"
When does string formatting run, and how do I avoid a runtime performance penalty?
If you are trying to close a duplicate question that is just looking for a way to format a string, please use How do I put a variable’s value inside a string?.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(16)
我会补充说,由于版本3.6,我们可以使用以下
fstrings
一切都转换为字符串
结果:
您可以通过函数,就像其他格式中的方法
给予
I would add that since version 3.6, we can use fstrings like the following
Which give
Everything is converted to strings
Result:
you can pass function, like in others formats method
Giving for example
Python 3.6.7比较:
输出:
Python 3.6.7 comparative:
Output:
对于Python版本&gt; = 3.6(请参阅 pep 498 )
For python version >= 3.6 (see PEP 498)
但是,还有一件事是,如果您嵌套了卷曲式,则无法用于格式,但
%
将起作用。例子:
But one thing is that also if you have nested curly-braces, won't work for format but
%
will work.Example:
要回答您的第一个问题...
.format
在许多方面似乎更复杂。关于%
的烦人的事情也是它如何服用变量或元组。您可能会认为以下内容总是有效的:但是,如果
name
恰好是(1,2,3)
,它将抛出type> typeerror
。为了确保它总是打印,您需要做这很丑陋。
.format
没有这些问题。同样,在您给出的第二个示例中,.format
示例看起来更干净。仅将其向后兼容与Python 2.5。
为了回答您的第二个问题,当评估字符串格式表达式时,字符串格式与任何其他操作同时进行。 python不是一种懒惰的语言,在调用函数之前评估表达式,因此expession
log.debug(“某些调试信息:%s“%some_info)
将首先评估字符串,例如>“某些调试信息:roflcopter处于活动状态” ,然后该字符串将传递给log.debug()
。To answer your first question...
.format
just seems more sophisticated in many ways. An annoying thing about%
is also how it can either take a variable or a tuple. You'd think the following would always work:yet, if
name
happens to be(1, 2, 3)
, it will throw aTypeError
. To guarantee that it always prints, you'd need to dowhich is just ugly.
.format
doesn't have those issues. Also in the second example you gave, the.format
example is much cleaner looking.Only use it for backwards compatibility with Python 2.5.
To answer your second question, string formatting happens at the same time as any other operation - when the string formatting expression is evaluated. And Python, not being a lazy language, evaluates expressions before calling functions, so the expression
log.debug("some debug info: %s" % some_info)
will first evaluate the string to, e.g."some debug info: roflcopters are active"
, then that string will be passed tolog.debug()
.Afaik:
结果
非常有用。
另一点:
格式()
作为一个函数,可以用作其他函数中的参数:结果:
Something that the modulo operator ( % ) can't do, afaik:
result
Very useful.
Another point:
format()
, being a function, can be used as an argument in other functions:Results in:
假设您正在使用Python的
记录
模块,则可以将字符串格式的参数作为参数传递给.debug()
方法而不是自己进行格式格式化除非记录器实际记录某些内容。
Assuming you're using Python's
logging
module, you can pass the string formatting arguments as arguments to the.debug()
method rather than doing the formatting yourself:which avoids doing the formatting unless the logger actually logs something.
从Python 3.6(2016)开始,您可以使用 替换变量:
f“
前缀。注意 a href =“ https://docs.python.org/3.6/reference/lexical_analysis.html#f-snrings” rel =“ noreferrer”> https://docs.python.org/3.6/reference/Rexical_analysis.htmllysis.htmll# f-strings
As of Python 3.6 (2016) you can use f-strings to substitute variables:
Note the
f"
prefix. If you try this in Python 3.5 or earlier, you'll get aSyntaxError
.See https://docs.python.org/3.6/reference/lexical_analysis.html#f-strings
pep 3101 建议更换
%
操作员借助Python 3中的新的高级字符串格式化,将是默认值。PEP 3101 proposes the replacement of the
%
operator with the new, advanced string formatting in Python 3, where it would be the default.但是请小心,刚才我在尝试将所有
%
用.format
中的所有%
中发现时发现了一个问题:'{}' .format(unicode_string)
将尝试编码unicode_string,并且可能会失败。只需查看此python Interactive session log:
s
只是一个字符串(称为'byte array''在python3中)和u
是一个Unicode字符串(python3中称为'String'):当您将Unicode对象作为参数作为
>%
运算符时,它将产生一个Unicode String即使原始字符串不是unicode:但是
.format
函数将引起“ unicodeCodeError”:仅当原始字符串是Unicode时,它才能与Unicode参数一起使用。
或者如果参数字符串可以转换为字符串(所谓的“字节数组”)
But please be careful, just now I've discovered one issue when trying to replace all
%
with.format
in existing code:'{}'.format(unicode_string)
will try to encode unicode_string and will probably fail.Just look at this Python interactive session log:
s
is just a string (called 'byte array' in Python3) andu
is a Unicode string (called 'string' in Python3):When you give a Unicode object as a parameter to
%
operator it will produce a Unicode string even if the original string wasn't Unicode:but the
.format
function will raise "UnicodeEncodeError":and it will work with a Unicode argument fine only if the original string was Unicode.
or if argument string can be converted to a string (so called 'byte array')
%
比我的测试中的格式
提供了更好的性能。测试代码:
Python 2.7.2:
结果:
Python 3.5.2
结果
在Python2中看起来很小,而在Python3中,
%
在form
中要快得多。感谢@chris Cogdon的示例代码。
编辑1:
在2019年7月再次在Python 3.7.2中进行测试。
结果:
没有太大的差异。我猜Python正在逐渐改善。
编辑2:
在有人提到Python 3的F-string之后,我对Python 3.7.2下的以下代码进行了测试:
结果:
F-string似乎仍然比
%
更慢,但是比格式
。%
gives better performance thanformat
from my test.Test code:
Python 2.7.2:
Result:
Python 3.5.2
Result
It looks in Python2, the difference is small whereas in Python3,
%
is much faster thanformat
.Thanks @Chris Cogdon for the sample code.
Edit 1:
Tested again in Python 3.7.2 in July 2019.
Result:
There is not much difference. I guess Python is improving gradually.
Edit 2:
After someone mentioned python 3's f-string in comment, I did a test for the following code under python 3.7.2 :
Result:
It seems f-string is still slower than
%
but better thanformat
..format
的另一个优点(在答案中我看不到):它可以占据对象属性。或者,作为关键字参数:
据我所知,这是不可能的。
Yet another advantage of
.format
(which I don't see in the answers): it can take object properties.Or, as a keyword argument:
This is not possible with
%
as far as I can tell.正如我今天发现的那样,通过
%
格式化字符串的旧方法不支持DECIMAL
,Python的模块用于小数固定点和浮点算术算术,以开箱即用。示例(使用Python 3.3.5):
输出:
肯定可能有工作障碍,但您仍然可以立即考虑使用
format()
立即使用。As I discovered today, the old way of formatting strings via
%
doesn't supportDecimal
, Python's module for decimal fixed point and floating point arithmetic, out of the box.Example (using Python 3.3.5):
Output:
There surely might be work-arounds but you still might consider using the
format()
method right away.如果您的python&gt; = 3.6,则是您的新朋友,F-string格式的字面形式是您的新朋友。
它更简单,干净和更好的性能。
If your python >= 3.6, F-string formatted literal is your new friend.
It's more simple, clean, and better performance.
附带说明,您不必进行性能命中即可使用日志记录使用新样式格式。您可以将任何对象传递到
logging.debug
,logging.info
等。当日志记录模块确定必须发射您的消息对象(无论它是什么)时,它在这样做之前调用str(Message_Object)
。因此,您可以做这样的事情:所有这些都在Python 3文档中描述( https://docs.python.org/3/howto/logging-cookbook.html#formatting-styles )。但是,它也将与python 2.6一起使用(“ noreferrer”> https://docs.python.org/2.6/library/logging.html#using-arbitrary-objects-as-messages )。
使用此技术的优点之一,除了其格式化式不可知论的事实是,它允许懒值
quode> quode> pundy_func
。这为这里的Python文档提供的建议提供了一种更优雅的替代方法: https: //docs.python.org/2.6/library/logging.html#optimization 。As a side note, you don't have to take a performance hit to use new style formatting with logging. You can pass any object to
logging.debug
,logging.info
, etc. that implements the__str__
magic method. When the logging module has decided that it must emit your message object (whatever it is), it callsstr(message_object)
before doing so. So you could do something like this:This is all described in the Python 3 documentation (https://docs.python.org/3/howto/logging-cookbook.html#formatting-styles). However, it will work with Python 2.6 as well (https://docs.python.org/2.6/library/logging.html#using-arbitrary-objects-as-messages).
One of the advantages of using this technique, other than the fact that it's formatting-style agnostic, is that it allows for lazy values e.g. the function
expensive_func
above. This provides a more elegant alternative to the advice being given in the Python docs here: https://docs.python.org/2.6/library/logging.html#optimization.%
可能会有所帮助的一种情况是您在格式化正则表达式时。例如,提高
indexError
。在这种情况下,您可以使用:这避免将正则表达式写为
'{type_names} [az] {{2}}}'
。当您有两个Regexes时,这可能很有用,其中一个是单独使用的,没有格式,但是两者的串联都格式化了。One situation where
%
may help is when you are formatting regex expressions. For example,raises
IndexError
. In this situation, you can use:This avoids writing the regex as
'{type_names} [a-z]{{2}}'
. This can be useful when you have two regexes, where one is used alone without format, but the concatenation of both is formatted.