译(三十八)-Python三种字符串格式化对比:% .format f‘string’
如有翻译问题欢迎评论指出,谢谢。
自我感觉今天的翻译更人话了点。
三种字符串格式化对比:% .format f‘string’
NorthIsUp asked:
- Python 2.6 有一个
str.format()
方法,和现有的%
操作符有点不同。它们各自更适合哪些情况? - Python 3.6 则提出了另一种字符串格式化语法
f"my string"
,它和其它方法又有什么优势?
下面代码使用了三种不同的方法,但输出相同,到底有啥区别?
#!/usr/bin/python sub1 = "python string!" sub2 = "an arg" # sub_a = "i am a %s" % sub1 sub_b = "i am a {0}".format(sub1) sub_c = f"i am a {sub1}" # arg_a = "with %(kwarg)s!" % {'kwarg':sub2} arg_b = "with {kwarg}!".format(kwarg=sub2) arg_c = f"with {sub2}!" # print(sub_a) # "i am a python string!" print(sub_b) # "i am a python string!" print(sub_c) # "i am a python string!" # print(arg_a) # "with an arg!" print(arg_b) # "with an arg!" print(arg_c) # "with an arg!"
此外,对于 Python 而言,应该在什么时候使用字符串格式化?比如日志级别设置为 HIGH 时使用
%
会不会有影响?如果有的话,怎么避免?log.debug("some debug info: %s" % some_info)
- Python 2.6 有一个
Answers:
Claudiu - vote: 976
对于第一个问题而言,
.format
更适合于大多数情况。%
有一点很讨厌,它能传入变量或元组,所以你可能觉得下面这样是正确的:"hi there %s" % name
但当
name
恰好是(1, 2, 3)
时,就会抛出TypeError
。而为了保证它始终有输出,就得这样:"hi there %s" % (name,) # supply the single argument as a single-item tuple
很丑对吧。
.format
就不会有这些毛病。而且对于你给出的第二个例子而言,.format
还更美观点。哪些情况下不会用到这个方法?
- 不清楚这个方式(没读到这之前我就是这样的)
- 为了和 Python 2.5 兼容
对于第二个问题而言,字符串格式化常常会与其它操作同时出现——字符串格式化会先于这些操作。Python 会在调用函数前先计算表达式结果,所以对于
log.debug
这个例子来说,表达式"some debug info: %s"%some_info
将首先得到"some debug info: roflcopters are active"
,然后再将字符串传给log.debug()
。eyquem - vote: 314
有些是模运算符
%
做不到的,据我所知下面的就不行:tu = (12,45,22222,103,6) print '{0} {2} {1} {2} {3} {2} {4} {2}'.format(*tu)
输出:
12 22222 45 22222 103 22222 6 22222
这玩意非常好使。
还有一点:
format()
作为方法,其值能被用作其它方法的参数:li = [12,45,78,784,2,69,1254,4785,984] print map('the number is {}'.format,li) # print # from datetime import datetime,timedelta # once_upon_a_time = datetime(2010, 7, 1, 12, 0, 0) delta = timedelta(days=13, hours=8, minutes=20) # gen =(once_upon_a_time +x*delta for x in xrange(20)) # print '\n'.join(map('{:%Y-%m-%d %H:%M:%S}'.format, gen))
输出:
['the number is 12', 'the number is 45', 'the number is 78', 'the number is 784', 'the number is 2', 'the number is 69', 'the number is 1254', 'the number is 4785', 'the number is 984'] # 2010-07-01 12:00:00 2010-07-14 20:20:00 2010-07-28 04:40:00 2010-08-10 13:00:00 2010-08-23 21:20:00 2010-09-06 05:40:00 2010-09-19 14:00:00 2010-10-02 22:20:00 2010-10-16 06:40:00 2010-10-29 15:00:00 2010-11-11 23:20:00 2010-11-25 07:40:00 2010-12-08 16:00:00 2010-12-22 00:20:00 2011-01-04 08:40:00 2011-01-17 17:00:00 2011-01-31 01:20:00 2011-02-13 09:40:00 2011-02-26 18:00:00 2011-03-12 02:20:00
Wooble - vote: 154
对于 Python 的
logging
模块而言,可以将字符串格式化的参数作为.debug()
方法的参数,这样就不用先自己格式化它了:log.debug("some debug info: %s", some_info)
这可以在没有东西需要格式化时,避免格式化操作。
String formatting: % vs. .format vs. f-string literal
NorthIsUp asked:
- Python 2.6 introduced the
str.format()
method with a slightly different syntax from the existing%
operator. Which is better and for what situations?
Python 2.6 有一个str.format()
方法,和现有的%
操作符有点不同。它们各自更适合哪些情况? - Python 3.6 has now introduced another string formatting format of string literals (aka f strings) via the syntax
f"my string"
. Is this formatting option better than the others?
Python 3.6 则提出了另一种字符串格式化语法f"my string"
,它和其它方法又有什么优势?
The following uses each method and has the same outcome, so what is the difference?
下面代码使用了三种不同的方法,但输出相同,到底有啥区别?#!/usr/bin/python sub1 = "python string!" sub2 = "an arg" # sub_a = "i am a %s" % sub1 sub_b = "i am a {0}".format(sub1) sub_c = f"i am a {sub1}" # arg_a = "with %(kwarg)s!" % {'kwarg':sub2} arg_b = "with {kwarg}!".format(kwarg=sub2) arg_c = f"with {sub2}!" # print(sub_a) # "i am a python string!" print(sub_b) # "i am a python string!" print(sub_c) # "i am a python string!" # print(arg_a) # "with an arg!" print(arg_b) # "with an arg!" print(arg_c) # "with an arg!"
Furthermore when does string formatting occur in Python? For example, if my logging level is set to HIGH will I still take a hit for performing the following
%
operation? And if so, is there a way to avoid this?
此外,对于 Python 而言,应该在什么时候使用字符串格式化?比如日志级别设置为 HIGH 时使用%
会不会有影响?如果有的话,怎么避免?log.debug("some debug info: %s" % some_info)
- Python 2.6 introduced the
Answers:
Claudiu - vote: 976
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:
对于第一个问题而言,.format
更适合于大多数情况。%
有一点很讨厌,它能传入变量或元组,所以你可能觉得下面这样是正确的:"hi there %s" % name
yet, if
name
happens to be(1, 2, 3)
, it will throw aTypeError
. To guarantee that it always prints, you\'d need to do
但当name
恰好是(1, 2, 3)
时,就会抛出TypeError
。而为了保证它始终有输出,就得这样:"hi there %s" % (name,) # supply the single argument as a single-item tuple
which is just ugly.
.format
doesn\'t have those issues. Also in the second example you gave, the.format
example is much cleaner looking.
很丑对吧。.format
就不会有这些毛病。而且对于你给出的第二个例子而言,.format
还更美观点。Why would you not use it?
哪些情况下不会用到这个方法?- not knowing about it (me before reading this)
不清楚这个方式(没读到这之前我就是这样的) - having to be compatible with Python 2.5
为了和 Python 2.5 兼容
- not knowing about it (me before reading this)
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 in your
log.debug
example, the expressionsome debug info: %s"%some_info
will first evaluate to, e.g."some debug info: roflcopters are active"
, then that string will be passed tolog.debug()
.
对于第二个问题而言,字符串格式化常常会与其它操作同时出现——字符串格式化会先于这些操作。Python 会在调用函数前先计算表达式结果,所以对于log.debug
这个例子来说,表达式"some debug info: %s"%some_info
将首先得到"some debug info: roflcopters are active"
,然后再将字符串传给log.debug()
。eyquem - vote: 314
Something that the modulo operator ( % ) can\'t do, afaik:
有些是模运算符%
做不到的,据我所知下面的就不行:tu = (12,45,22222,103,6) print '{0} {2} {1} {2} {3} {2} {4} {2}'.format(*tu)
result
输出:12 22222 45 22222 103 22222 6 22222
Very useful.
这玩意非常好使。Another point:
format()
, being a function, can be used as an argument in other functions:
还有一点:format()
作为方法,其值能被用作其它方法的参数:li = [12,45,78,784,2,69,1254,4785,984] print map('the number is {}'.format,li) # print # from datetime import datetime,timedelta # once_upon_a_time = datetime(2010, 7, 1, 12, 0, 0) delta = timedelta(days=13, hours=8, minutes=20) # gen =(once_upon_a_time +x*delta for x in xrange(20)) # print '\n'.join(map('{:%Y-%m-%d %H:%M:%S}'.format, gen))
Results in:
输出:['the number is 12', 'the number is 45', 'the number is 78', 'the number is 784', 'the number is 2', 'the number is 69', 'the number is 1254', 'the number is 4785', 'the number is 984'] # 2010-07-01 12:00:00 2010-07-14 20:20:00 2010-07-28 04:40:00 2010-08-10 13:00:00 2010-08-23 21:20:00 2010-09-06 05:40:00 2010-09-19 14:00:00 2010-10-02 22:20:00 2010-10-16 06:40:00 2010-10-29 15:00:00 2010-11-11 23:20:00 2010-11-25 07:40:00 2010-12-08 16:00:00 2010-12-22 00:20:00 2011-01-04 08:40:00 2011-01-17 17:00:00 2011-01-31 01:20:00 2011-02-13 09:40:00 2011-02-26 18:00:00 2011-03-12 02:20:00
Wooble - vote: 154
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:
对于 Python 的logging
模块而言,可以将字符串格式化的参数作为.debug()
方法的参数,这样就不用先自己格式化它了:log.debug("some debug info: %s", some_info)
which avoids doing the formatting unless the logger actually logs something.
这可以在没有东西需要格式化时,避免格式化操作。
共有 0 条评论