'%s in %s'
のような文字列があり、2つの異なる%になるように引数を分離する方法を知りたいです。 Javaからの私の心はこれを思い付きました:
'%s in %s' % unicode(self.author), unicode(self.publication)
しかし、これは機能しないので、Pythonでどのように見えますか?
Mark Cidadeの答えは正しいです-タプルを提供する必要があります。
ただし、Python 2.6以降では、%
の代わりに format
を使用できます。
'{0} in {1}'.format(unicode(self.author,'utf-8'), unicode(self.publication,'utf-8'))
文字列のフォーマットに%
を使用することは推奨されなくなりました。
この文字列フォーマットの方法はPython 3.0の新しい標準であり、新しいコードの文字列フォーマット操作で説明されている%フォーマットよりも優先されるべきです。
複数の引数を使用している場合、タプル内にある必要があります(余分な括弧に注意してください):
'%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
のTuple/mappingオブジェクト以下は、ドキュメントからの抜粋です。
format % values
を指定すると、format
の%
変換仕様は、values
のゼロ個以上の要素に置き換えられます。この効果は、C言語でsprintf()
を使用するのと似ています。
format
が単一の引数を必要とする場合、値は単一の非タプルオブジェクトである場合があります。 それ以外の場合、値はformat
string、、または単一のマッピングで指定されたアイテムの数だけのタプルでなければなりませんobject(たとえば、辞書)。
str.format
ではなく%
で%
演算子の新しい代替手段は、str.format
を使用することです。ドキュメントからの抜粋を次に示します。
str.format(*args, **kwargs)
文字列のフォーマット操作を実行します。このメソッドが呼び出される文字列には、リテラルテキストまたは中括弧
{}
で区切られた置換フィールドを含めることができます。各置換フィールドには、位置引数の数値インデックス、またはキーワード引数の名前が含まれます。各置換フィールドが対応する引数の文字列値で置換された文字列のコピーを返します。このメソッドはPython 3.0の新しい標準であり、
%
formatingよりも優先されるべきです。
以下に使用例を示します。
>>> '%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
値を括弧に入れるだけです:
'%s in %s' % (unicode(self.author), unicode(self.publication))
ここでは、最初の%s
にunicode(self.author)
が配置されます。 2番目の%s
には、unicode(self.publication)
が使用されます。
注:
string formatting
表記よりも%
を優先する必要があります。詳細 こちら
これまでに投稿された回答のいくつかには重大な問題があります: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'))
(または、Unicodeの結果が必要かバイト文字列が必要かによって、最初のu
なし)。
この時点で、author
およびpublication
フィールドをフォーマット中にデコードするのではなく、Unicode文字列にすることを検討することができます。
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)
また、次のようにすることで、クリーンでシンプルに使用できます(ただし、間違っています!Mark Byersが言ったようにformat
を使用する必要があるためです)。
print 'This is my %s formatted with %d arguments' % ('string', 2)