Pythonの文字列フォーマットに複数の引数を使用する(例: '%s…%s')


174

次のような文字列があり、'%s in %s'2つの異なる%sになるように引数を分離する方法を知りたいです。Javaから来る私の心はこれを思い付きました:

'%s in %s' % unicode(self.author),  unicode(self.publication)

しかし、これは機能しないので、Pythonではどのように見えますか?

回答:


191

Mark Cidadeの答えは正しいです。タプルを提供する必要があります。

ただし、Python 2.6以降formatでは、%次の代わりに使用できます。

'{0} in {1}'.format(unicode(self.author,'utf-8'),  unicode(self.publication,'utf-8'))

%文字列をフォーマットするためのの使用は推奨されなくなりました。

この文字列フォーマットの方法は、Python 3.0の新しい標準であり、新しいコードの文字列フォーマット操作で説明されている%フォーマットよりも推奨されます。


5
また、Python 2.7以降では、インデックス番号を削除でき'{} in {}'ます。つまり、プレーンなフォーマット文字列を使用できます。
クリスティアンCiupitu 2015年

121

複数の引数を使用している場合は、タプルで指定する必要があります(余分な括弧に注意してください)。

'%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'))

60

複数の引数のタプル/マッピングオブジェクト format

以下はドキュメントからの抜粋です。

の場合format % values、の%変換指定はのformat0個以上の要素に置き換えられますvalues。効果はsprintf()、C言語での使用に似ています。

format単一の引数が必要な場合、値は単一の非タプルオブジェクトの場合があります。それ以外の場合、値は、formatstring指定されたアイテム数と同じタプルまたは単一のマッピングオブジェクト(ディクショナリなど)である必要があります。

参考文献


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

こちらもご覧ください


これをテストする方法はありません(Pythonについてはあまり知りません)が、例のようなもの'{self.author} in {self.publication}'.format(self=self)が「機能する」ことを示唆しているようです。全体についてはよくわかりませんunicode
polygenelubricants

1
はい、実際に属性(およびインデックス)にアクセスできます。docs.python.org/library/string.html#formatstringsを参照してください したがって、この例では{first[0]}、初期値を取得するために使用できますJ
ダンカン

10

値を括弧に入れる必要があります:

'%s in %s' % (unicode(self.author),  unicode(self.publication))

ここでは、最初のために配置されます。そして2番目のには、が使用されます。%sunicode(self.author)%sunicode(self.publication)

注:表記string formattingよりも優先する必要があり%ます。詳細はこちら


私は人々がまだ提案するの%sではなく、信じられませんformat
user1767754

8

これまでに投稿された回答のいくつかには重大な問題があり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)

この失敗は、authorASCIIバイトだけが含まれていない(つまり、[0; 127]の値を持つ)ために発生unicode()し、デフォルトで(多くのマシンでは)ASCIIからデコードされます。

堅牢なソリューションは、フィールドで使用されるエンコードを明示的に指定することです。UTF-8を例にとります:

u'{0} in {1}'.format(unicode(self.author, 'utf-8'), unicode(self.publication, 'utf-8'))

(またはu、Unicodeの結果が必要かバイト文字列が必要かによっては、最初のなし)。

この時点で、フォーマット中にデコードするのではなくauthorpublicationフィールドとフィールドをUnicode文字列にすることを検討することをお勧めします。


5

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)

4

次のようにすることで、クリーンでシンプルな方法で使用することもできます(ただし、formatMark Byersが言ったように使用する必要があるため、間違っています)。

print 'This is my %s formatted with %d arguments' % ('string', 2)

3

完全を期すために、Python 3.6ではf-stringがPEP-498で導入されています。これらの文字列により、

最小限の構文を使用して、文字列リテラル内に式を埋め込みます。

それはあなたの例ではあなたがまた使うことができることを意味します:

f'{self.author} in {self.publication}'
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.