用一个变量格式化多个 %s
Formatting multiple %s with a single variable
我有一个 %s
数量未知的字符串,需要使用单个字符串进行格式化。
例如,如果我有字符串 "%s some %s words %s"
并想用单词 house
格式化它,它应该输出 "house some house words house"
执行以下操作会出现错误:
>>> "%s some %s words %s" % ("house")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: not enough arguments for format string
所以,我决定执行以下操作,虽然可行,但对于这样一个简单的问题来说似乎过于复杂。
var = "house"
tup = (var,)
while True:
try:
print "%s some %s words %s" % tup
break
except:
tup += (var,)
是否有更 pythonic 的方式来做到这一点?
如果你确定你要替换%s
,你可以这样做:
var = "house"
tup = (var,)
txt = "%s some %s words %s"
print txt % (tup * txt.count("%s"))
但更好的解决方案是使用 str.format()
,它使用不同的语法,但允许您按编号指定项目,因此您可以重复使用它们:
var = "house"
txt = "{0} some {0} words {0}"
print txt.format(var)
为什么不使用 format
?
"{0} some {0} words {0}".format("house")
这里有几个选项:
格式化字符串(和 Formatter class)
使用str.format
是最pythonic 的方式并且非常易于阅读。两种风格都受欢迎:
位置参数
'{0} some {0} words {0}'.format('house')
命名参数
'{word} some {word} words {word}'.format(word='house')
您在评论中提到由于其他遗留代码而保留原始格式字符串。你可以像这样破解:
'%s some %s words %s'.replace('%s', '{0}').format('house')
(我不推荐它,但您可以通过在替换调用中使用 'house'
而不是 '{0}'
来 "short circuit" 这个想法行。)
也就是说,我真的认为首先更改模板字符串是一个更好的主意。
模板字符串
在浏览了 string
文档后,又想到了一个替代方案:较旧的 string.Template
class。默认情况下,它替换基于 $
的值,但您可以 subclass 它覆盖定界符。例如:
class MyTemplate(Template):
"""
Overriding default to maintain compatibility with legacy code.
"""
delimiter = '%'
t = MyTemplate('%s some %s words %s')
t.substitute(s='house')
请记住,这不太常见,但您可以编写一次并在每次使用这样的字符串时重新使用它(假设只有一个输入值被替换)。至少写一次Pythonic!
文字字符串插值
在Python 3.6 中,Ruby-style string interpolation 是另一个社区尚未达成共识的选项。例如:
s = 'house'
f'{s} some {s} words {s}'
我有一个 %s
数量未知的字符串,需要使用单个字符串进行格式化。
例如,如果我有字符串 "%s some %s words %s"
并想用单词 house
格式化它,它应该输出 "house some house words house"
执行以下操作会出现错误:
>>> "%s some %s words %s" % ("house")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: not enough arguments for format string
所以,我决定执行以下操作,虽然可行,但对于这样一个简单的问题来说似乎过于复杂。
var = "house"
tup = (var,)
while True:
try:
print "%s some %s words %s" % tup
break
except:
tup += (var,)
是否有更 pythonic 的方式来做到这一点?
如果你确定你要替换%s
,你可以这样做:
var = "house"
tup = (var,)
txt = "%s some %s words %s"
print txt % (tup * txt.count("%s"))
但更好的解决方案是使用 str.format()
,它使用不同的语法,但允许您按编号指定项目,因此您可以重复使用它们:
var = "house"
txt = "{0} some {0} words {0}"
print txt.format(var)
为什么不使用 format
?
"{0} some {0} words {0}".format("house")
这里有几个选项:
格式化字符串(和 Formatter class)
使用str.format
是最pythonic 的方式并且非常易于阅读。两种风格都受欢迎:
位置参数
'{0} some {0} words {0}'.format('house')
命名参数
'{word} some {word} words {word}'.format(word='house')
您在评论中提到由于其他遗留代码而保留原始格式字符串。你可以像这样破解:
'%s some %s words %s'.replace('%s', '{0}').format('house')
(我不推荐它,但您可以通过在替换调用中使用 'house'
而不是 '{0}'
来 "short circuit" 这个想法行。)
也就是说,我真的认为首先更改模板字符串是一个更好的主意。
模板字符串
在浏览了 string
文档后,又想到了一个替代方案:较旧的 string.Template
class。默认情况下,它替换基于 $
的值,但您可以 subclass 它覆盖定界符。例如:
class MyTemplate(Template):
"""
Overriding default to maintain compatibility with legacy code.
"""
delimiter = '%'
t = MyTemplate('%s some %s words %s')
t.substitute(s='house')
请记住,这不太常见,但您可以编写一次并在每次使用这样的字符串时重新使用它(假设只有一个输入值被替换)。至少写一次Pythonic!
文字字符串插值
在Python 3.6 中,Ruby-style string interpolation 是另一个社区尚未达成共识的选项。例如:
s = 'house'
f'{s} some {s} words {s}'