【发布时间】:2011-03-24 15:13:32
【问题描述】:
我有一个看起来像 '%s in %s' 的字符串,我想知道如何分隔参数,以便它们是两个不同的 %s。我从 Java 中想到了这个:
'%s in %s' % unicode(self.author), unicode(self.publication)
但这不起作用,那么它在 Python 中的外观如何?
【问题讨论】:
我有一个看起来像 '%s in %s' 的字符串,我想知道如何分隔参数,以便它们是两个不同的 %s。我从 Java 中想到了这个:
'%s in %s' % unicode(self.author), unicode(self.publication)
但这不起作用,那么它在 Python 中的外观如何?
【问题讨论】:
如果你使用多个参数,它必须在一个元组中(注意额外的括号):
'%s in %s' % (unicode(self.author), unicode(self.publication))
正如 EOL 指出的那样,unicode() 函数通常假定 ascii 编码为默认值,因此如果您有非 ASCII 字符,则显式传递编码会更安全:
'%s in %s' % (unicode(self.author,'utf-8'), unicode(self.publication('utf-8')))
从 Python 3.0 开始,最好使用 str.format() 语法:
'{0} in {1}'.format(unicode(self.author,'utf-8'),unicode(self.publication,'utf-8'))
【讨论】:
format
以下内容摘自文档:
给定
format % values,format中的%转换规范将替换为values的零个或多个元素。效果类似于C语言中使用sprintf()。如果
format需要单个参数,则值可能是单个非元组对象。 否则,值必须是与format字符串指定的项目数完全相同的元组,或单个映射对象(例如,字典)。 p>
str.format 而不是%
% 运算符的更新替代方法是使用 str.format。以下是文档的摘录:
str.format(*args, **kwargs)执行字符串格式化操作。调用此方法的字符串可以包含由大括号
{}分隔的文字文本或替换字段。每个替换字段都包含位置参数的数字索引或关键字参数的名称。返回字符串的副本,其中每个替换字段都替换为相应参数的字符串值。此方法是 Python 3.0 中的新标准,应优先于
%格式化。
以下是一些用法示例:
>>> '%s for %s' % ("tit", "tat")
tit for tat
>>> '{} and {}'.format("chicken", "waffles")
chicken and waffles
>>> '%(last)s, %(first)s %(last)s' % {'first': "James", 'last': "Bond"}
Bond, James Bond
>>> '{last}, {first} {last}'.format(first="James", last="Bond")
Bond, James Bond
【讨论】:
'{self.author} in {self.publication}'.format(self=self) 这样的东西应该“工作”。我只是不确定整个unicode 的事情。
{first[0]} 来获取初始的J。
Mark Cidade 的回答是正确的 - 您需要提供一个元组。
但是,从 Python 2.6 开始,您可以使用 format 而不是 %:
'{0} in {1}'.format(unicode(self.author,'utf-8'), unicode(self.publication,'utf-8'))
不再鼓励使用% 格式化字符串。
这种字符串格式化方法是 Python 3.0 中的新标准,应该优先于新代码中字符串格式化操作中描述的 % 格式化。
【讨论】:
'{} in {}' 格式字符串。
对于python2你也可以这样做
'%(author)s in %(publication)s'%{'author':unicode(self.author),
'publication':unicode(self.publication)}
如果您有很多要替换的参数(尤其是在进行国际化时),这很方便
Python2.6 以上支持.format()
'{author} in {publication}'.format(author=self.author,
publication=self.publication)
【讨论】:
到目前为止发布的一些答案存在一个重大问题:unicode() 从默认编码解码,通常是 ASCII;事实上,unicode() 试图通过将其转换为字符来“理解”给出的字节。因此,以下代码(基本上是先前答案所推荐的)在我的机器上失败了:
# -*- coding: utf-8 -*-
author = 'éric'
print '{0}'.format(unicode(author))
给予:
Traceback (most recent call last):
File "test.py", line 3, in <module>
print '{0}'.format(unicode(author))
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)
失败是因为author 不只包含 ASCII 字节(即在 [0; 127] 中的值),并且unicode() 默认从 ASCII 解码(在许多机器上)。
一个可靠的解决方案是明确给出字段中使用的编码;以 UTF-8 为例:
u'{0} in {1}'.format(unicode(self.author, 'utf-8'), unicode(self.publication, 'utf-8'))
(或者没有初始的u,取决于你想要的是Unicode结果还是字节字符串)。
此时,可能需要考虑将author 和publication 字段设为Unicode 字符串,而不是在格式化期间对其进行解码。
【讨论】:
您也可以通过以下方式干净简单地使用它(但错误!因为您应该像 Mark Byers 所说的那样使用format):
print 'This is my %s formatted with %d arguments' % ('string', 2)
【讨论】:
您必须将值放入括号中:
'%s in %s' % (unicode(self.author), unicode(self.publication))
在这里,对于第一个%s,将放置unicode(self.author)。而对于第二个%s,将使用unicode(self.publication)。
注意:您应该更喜欢
string formatting而不是%表示法。更多信息here
【讨论】:
%s 而不是format
为了完整起见,在 python 3.6 中,PEP-498 中引入了 f-string。这些字符串可以
在字符串文字中嵌入表达式,使用最少的语法。
这意味着对于您的示例,您还可以使用:
f'{self.author} in {self.publication}'
【讨论】: