还有其他格式化字符串的方法吗,除了逗号、百分号和加号?
我一直在寻找这个问题的答案,但没有找到明确的说法:在Python中打印变量的推荐方法是什么?
到目前为止,我看到三种方法:用逗号、用百分号,或者用加号:
>>> a = "hello"
>>> b = "world"
>>> print a, "to the", b
hello to the world
>>> print "%s to the %s" % (a, b)
hello to the world
>>> print a + " to the " + b
hello to the world
每种方法似乎都有自己的优缺点。
用逗号可以直接写变量,还能自动加空格,如果需要的话,也会自动把变量转换成字符串。不过我记得好的编码习惯是最好把变量和文本分开。
用百分号的方法可以做到这一点,但如果有多个变量,就需要用列表来处理,而且还得写出变量的类型(虽然即使变量类型不一样,比如用%s打印数字,它也能转换)。
用加号的方法似乎是“最差”的,因为它把变量和文本混在一起,而且不会自动转换;不过有时候可能需要对变量有更多的控制。
我查了一下,似乎这些方法中的一些现在可能已经过时了。既然它们都能工作,而且各有优缺点,我在想:有没有推荐的方法,还是说这都要看具体情况?
4 个回答
这要看你用的是哪个版本。
如果是Python 2,写法很简单:
print 'string'
print 345
print 'string'+(str(345))
print ''
但是Python 3需要加上括号(我个人希望它不需要这样)。
print ('string')
print (345)
print ('string'+(str(345))
还有一种最保险的方法就是把所有内容都转换成一个变量:
a = 'string'
b = 345
c = str(345)
d = a + c
问题是,你想打印变量(情况1),还是想输出格式化的文本(情况2)。情况1比较简单,通常用于调试输出。如果你想以特定的方式表达内容,格式化会是更好的选择。用'+'来拼接字符串并不是Python推荐的做法。
除了'%',还有一种替代方法是"{0} to the {1}".format(a,b)
,自Python 3起,这种格式化方式更受欢迎。
在字符串中包含标识符的值叫做字符串格式化。处理字符串格式化的方法有很多种,每种方法都有优缺点。
- 使用字符串拼接(
+
):- 缺点:你必须手动把对象转换成字符串
- 优点:对象可以放在你想要的位置
- 缺点:最终的排版可能不太清晰,因为字符串被拆开了
- 使用模板字符串(也就是
$bash-style
替换):- 优点:你可能对shell变量扩展比较熟悉
- 优点:字符串转换会自动完成
- 优点:最终的排版很清晰
- 缺点:你无法指定如何进行转换
- 使用
%
风格的格式化:- 优点:和C语言的
printf
格式化类似 - 优点:转换会自动为你完成
- 优点:你可以指定不同类型的转换,还有一些选项(比如
float
的精度) - 优点:最终的排版很清晰
- 优点:你还可以指定替换元素的名称,比如:
%(name)s
。 - 缺点:你无法自定义格式说明符的处理方式
- 缺点:有些特殊情况可能会让你困惑。为了避免这些情况,你应该始终使用
tuple
或dict
作为参数。
- 优点:和C语言的
- 使用
str.format
:- 拥有
%
风格格式化的所有优点(除了它和printf
不太相似) - 类似于.NET的
String.Format
- 优点:你可以手动指定编号字段,这样可以多次使用位置参数
- 优点:格式说明符有更多选项
- 优点:你可以在自定义类型中自定义格式说明符
- 拥有
逗号并不进行字符串格式化。它们是print
语句的语法部分。逗号有一个“软空格”的“特性”,在python3中这个特性消失了,因为print
现在是一个函数:
>>> print 'something\t', 'other'
something other
>>> print 'something\tother'
something other
注意上面的输出是完全相同的,即使第一个使用了逗号。这是因为在某些情况下,逗号不会引入空格(例如,紧接在制表符或换行符后面)。
在python3中,这种情况不会发生:
>>> print('something\t', 'other')
something other
>>> print('something\tother') # note the difference in spacing.
something other
自从python2.6开始,推荐的字符串格式化方式是使用str.format
方法。它是为了替代%
风格的格式化,尽管目前没有计划(我认为也不会有)去移除%
风格的格式化。
string.format() 基础知识
这里有几个基本的字符串替换示例,{} 是用来放置替换变量的地方。如果没有指定格式,它会将内容作为字符串插入并格式化。
s1 = "so much depends upon {}".format("a red wheel barrow")
s2 = "glazed with {} water beside the {} chickens".format("rain", "white")
你还可以使用变量的数字位置来改变字符串中的顺序,这样在格式化时就更灵活了。如果你在顺序上出错了,可以很容易地纠正,而不需要把所有变量都重新调整。
s1 = " {0} is better than {1} ".format("emacs", "vim")
s2 = " {1} is better than {0} ".format("emacs", "vim")
format() 函数提供了很多额外的功能和能力,这里有一些使用 .format() 的实用技巧。
命名参数
你可以把新的字符串格式当作模板引擎来使用,使用命名参数,而不需要严格的顺序。
madlib = " I {verb} the {object} off the {place} ".format(verb="took", object="cheese", place="table")
>>> I took the cheese off the table
多次重用同一个变量
使用 % 格式化器时,需要严格按照变量的顺序,而 .format() 方法允许你像上面所示那样随意排列顺序,还可以重用变量。
str = "Oh {0}, {0}! wherefore art thou {0}?".format("Romeo")
>>> Oh Romeo, Romeo! wherefore art thou Romeo?
将格式作为函数使用
你可以把 .format 当作一个函数来使用,这样可以将文本和格式与代码分开。例如,在程序开始时,你可以定义好所有的格式,然后在后面使用。这也是处理国际化的一个好方法,因为国际化不仅需要不同的文本,通常还需要不同的数字格式。
email_f = "Your email address was {email}".format
print(email_f(email="bob@example.com"))
转义大括号
如果在使用 str.format() 时需要使用大括号,只需将它们加倍即可。
print(" The {} set is often represented as {{0}} ".format("empty"))
>>> The empty set is often represented as {0}