文字列のフォーマットは、ほとんどのプログラマにとって遅かれ早かれ必要悪となる。シッククライアントGUIの時代以前はそうでしたが、特定の文字列を表現する必要性は今でも十分に一般的なユースケースです。私の最初の出会いは大学時代で、古風な教授が私たちにJavaのコンソールアプリケーションを書かせ、 printf(...)
関数で出力するための神経質な仕様を書かせるという不純な愛を持っていた時です。当時も今も変わらないのは、文字列のフォーマットに関するドキュメントが(実質的にすべての言語で)望まれることがたくさんあるということです。今日は、Pythonで文字列のフォーマットを行う方法について書くことで、この苦痛を和らげたいと思います。
Pythonには文字列をフォーマットするための複数のテクニックがあり、正確には4つあります。興味深いことに、これはあるタスクを達成するための明確なベストの方法があるべきだというPythonの考え方にちょっと逆行するものです。しかし、もしあなたがPythonにそれなりの時間を費やしてきたのなら、おそらくこれらの異なるテクニックの配列を見て、「これってどうなんだろう」と思ったことがあるはずです。
文字列の4つの書式設定の実行方法
まず最初に、最も一般的な「%」演算子を使った方法から説明します。最も一般的というのは、この方法が最も長く使われていて、あちこちで見かけるからです(書籍、ブログ記事、Stack Overflowなどなど)。この方法を利用するには、文字列の場合は %s
を、数値の場合は %d
を使って文字列のプレースホルダを指定します。
>>> "Hello reader, welcome to the %s form of string formatting." % 'modulus'
'Hello reader, welcome to the modulus form of string formatting.'
>>>
>>> "Formatting multiple (%d, %d, %d, ...) values requires a %s." % (1, 2, 3, 'tuple')
'Formatting multiple (1, 2, 3, ...) values requires a tuple.'
>>>
>>> print("""If you prefer named placeholders for values %(one)d, %(two)d,
... %(three)d ... you can use a dict""" % {'one':1, 'two':2, 'three':3})
If you prefer named placeholders for values 1, 2,
3 ... you can use a dict
次に取り上げるテクニックは str.format(...)
メソッドです。これは前に紹介した %
スタイルの代替となることを意図しています。このテクニックは、中括弧 {}
を使って、値を文字列にフォーマットする場所と方法を指定します。
>>> "Hello reader, welcome to the {} form of string formatting".format('str.format(...)')
'Hello reader, welcome to the str.format(...) form of string formatting'
>>>
>>> print("""Formatting multiple ({0}, {1}, {2}, ...) values requires
... that you use multiple {3} brackets and optionally specify ordering
... values.""".format(1,2,3,'{}'))
Formatting multiple (1, 2, 3, ...) values requires
that you use multiple {} brackets and optionally specify ordering
values.
>>>
>>> print("""The {language} str.format() method also allows you to use
... named parameters which help keep code {adjective}
... """.format(language='Python', adjective='concise'))
The Python str.format() method also allows you to use
named parameters which help keep code concise
次に、stringモジュールのクラスであるstring Templateのテクニックがあります。この文字列フォーマット方法は、前の2つとは異なり、もう少し冗長で、型指定子(s, d, f, etc…)もサポートしていません。この方法では、Template(...)
クラスのコンストラクタで、希望する値の前に $
を付けて文字列のプレースホルダを指定し、その後、インスタンス化したオブジェクトの substitute(...)
メソッドを名前付きのパラメータで呼び出します。この方法は、パワーと柔軟性が低下するため、はるかに一般的ではありません。
>>> from string import Template
>>> tmpl = Template("Hello my name is $name")
>>> tmpl.substitute(name='Adam')
'Hello my name is Adam'
最後のテクニックは、Python 3.6でのみ利用可能な最も新しい実装で、文字列補間として知られています。これはJavascriptのES6テンプレート文字列に類似しています。文字列補間では、文字列リテラルの前に f""
を付ける必要があり、 {}
ブラケットで囲む限り、文字列内で式と変数の両方を直接指定することができます。
>>> method="String Interpolation"
>>> f"Hello reader, I am the {method} of formatting"
'Hello reader, I am the String Interpolation of formatting'
>>>
>>> f"With this method you can have expressions like {{1 + 1}} = {1 + 1}"
'With this method you can have expressions like {1 + 1} = 2'
文字列の書式を深く掘り下げる
以下の章では、文字列の書式設定に適した方法である str.format()
メソッドと f""
補間技法だけに絞って話をします。より深く掘り下げたいトピックは以下の通りです。
- テキストのアライメント
- 数値の書式設定
- 型変換
str.format()と補間手法は、
{}ブラケットの間でフォーマットを定義する同じシンタックスを共有します。このブラケットでは、
:`を使用して、左側に名前または序数を持つ識別子、右側にフォーマット指定を分離します。
テキストアライメント
左揃え、右揃え、中央揃えをそれぞれ <
, >
, ^
という記号で指定すると、指定した長さの文字列の中で値を揃えることができます。そして、これらの記号の後に、希望する文字幅を指定します。
Python > 2.6:
>>> left_aligned = "Left Align"
>>> center = "Centered"
>>> right_aligned = "Right Align"
>>> "{left_aligned:<15}{center:^10}{right_aligned:>15}".format(
... left_aligned=left_aligned,
... center=center,
... right_aligned=right_aligned)
'Left Align Centered Right Align'
キーワードではなく、序列を指定することもできます。
>>> "{1:<15}{0:^10}{2:>15}".format(center, left_aligned, right_aligned)
'Left Align Centered Right Align'
また、format(...)
のパラメータの順番が {}
の順番と同じであれば、省略することができます。
>>> "{:<15}{:^10}{:>15}".format(left_aligned, center, right_aligned)
'Left Align Centered Right Align'
Python 3.6:
>>> f"{left_aligned:<15}{center:^10}{right_aligned:>15}"
'Left Align Centered Right Align'
これまでの例では、残りのパディングされたスペースを暗黙のうちに空白で埋めました。これは、デフォルトの動作です。しかし、これが望ましくない場合は、コロンのすぐ後に文字を指定することで、何か別のもので埋めることができます。
Python > 2.6:
>>> "{:><15}|{:-^10}|{:<>15}".format(left_aligned, center, right_aligned)
'Left Align>>>>>|-Centered-|<<<<right 3.6:="" ```="" align'="" python="">>> f"{left_aligned:><15}{center:-^10}{right_aligned:<>15}"
'左揃え>>>-中央揃え<<<右###="" ```="" `f`.="" a="" align'="" all="" an="" cinch="" colon="" containing="" decimal="" do="" floating="" follow="" formatting="" in="" is="" need="" numbers="" numbers,="" places,="" point="" python="" python.="" the="" those="" to="" with="" you=""> 2.6:
>>> rounded_pi = 3.14
>>> “円周率{:f}の丸められた表現”.format(rounded_pi)
‘円周率3.140000の丸められた表現’
Python 3.6:
>>> f “円周率の丸められた表現{rounded_pi:f}”
‘円周率3.140000の丸められた表現’
Notice that the string has six decimal places. This is because by default the float specifier is given six places which it will either fill with zeros or round to only contain six depending on the input. For example, if I import the longer pi constant from the math module you'll see the rounding in action.
Python > 2.6:
>>> from math import pi
>>> 円周率
3.141592653589793
>>> “円周率{:f}の丸められた表現”.format(pi)
‘円周率3.141593の丸められた表現’
Python 3.6:
>>> f “円周率{pi:f}の丸められた表現”
‘円周率3.141593の丸められた表現’
To specify a different precision (number of decimal places) simply precede the `f` by the number of decimal places desired like so.
Python > 2.6:
>>> “円周率{:.3f}の丸められた表現”.format(pi)
‘円周率3.142の丸められた表現’
Python 3.6:
>>> f “円周率{pi:.3f}の丸められた表現”
‘円周率3.142の丸められた表現’
Another formatting use-case for floating point numbers is the percent specifier. This works by converting what is expected to be a proportion or ratio (0-1) to a value out of 100 and treats the leftover decimal portion similar to the `f` specifier with a default precision of six.
Python > 2.6:
>>> レセプタクル = 17
>>> パス = 29
>>> 「完走率は{:.2%}」.format(レセプション数/パス数)
「完走率は58.62%です
Python 3.6:
>>> f “The completion percentage is {receptions/passes:.2%}”.
‘完了率は58.62%です’
Ok, so that takes care of most use cases involving floating point numbers, but what about large numbers? Python also has support for formatting these by putting in commas to increase readability of large numbers. To take advantage of this simply place a `,` after the colon.
Python > 2.6:
>>> house_price = 299999.99
>>> “家の値段は${:,}”.format(house_price)
‘家の値段は299999.99ドルです’
Python 3.6:
>>> f “家の値段は${house_price:,}です。”
‘家の値段は299,999.99ドルです’
#### Type Conversions
Type conversions are a bit of a less common use case but, they do come up from time to time. The major type conversions are the following for numbers:
| Conversion | Description |
| --- | --- |
| b | Binary |
| o | Octal |
| x | Hexadecimal |
| d | Decimal |
As with the other format specifiers they work by adding them after the colon. Hopefully this general pattern of formatting syntax is becoming clear to you.
Python > 2.6:
>>> 数値 = 157
>> print(“Binary: {:b}nOctal {:o}nHexadecimal: {:x}nDecimal: {:d}”.format()。
… 数値
…数,
… 数
…数))
2進数: 10011101
8進数 235
16進法: 9d
10進数: 157
Python 3.6:
>>> print(f “Binary: {number:b}nOctal {number:o}nHexadecimal: {number:x}nDecimal: {number:d}”)
2進数:10011101
8進数 235
16進法: 9d
10進法: 157
“`
結論
この文字列フォーマットに関する簡単なチュートリアルでは、ほとんど表面しか見ていませんが、日々のPythonプログラムで遭遇する可能性のある一般的な使用例について、いくつかの具体例を示すことができたと思います。私の目標は、文字列フォーマットの構文と実装テクニックの基本的な説明を提供することでした。ここから、あなたはドキュメントの詳細を掘り下げるのに十分な理解力を身につけることができるはずです。読み進めていただきありがとうございます。また、以下に自由にコメントしてください。
<strong