ログファイルでは、以下のようにファイル名に日付を含めることがよくあります。

file_20180904.txt

日付の部分(20180904)は毎日変わるのでコードで毎回作成し直す必要がありますが、その方法として以下の4通りが考えられます。

  1. 連結演算子(+)を使用する。
  2. 従来からの%構文による文字列フォーマットを使用する。
  3. 文字列のformat()メソッドによる文字列フォーマットを使用する(Python3から可能)。
  4. 新しいf文字列を使用する(Python3.6から可能)

Pythonのコードでは、以下のようになります。

from datetime import datetime 

# 今日の日付(例:20180904)
today = datetime.now().strftime("%Y%m%d") 

# 1. 連結演算子を使用
file_1 = "file_" + today + ".txt"

# 2. %構文を使用
file_2 = "file_%s.txt" % today

# 3. formatメソッドを使用
file_3 = "file_{}.txt".format(today)

# 4. f文字列を使用
file_4 = f"file_{today}.txt"
# 結果はすべて同じ(例:file_20180904.txt)

どの方法を用いるかは、好みの問題ですが、Python3が一般的になった現在ではformat()メソッド、さらにPython3.6以上であればf文字列を使うのが便利です。何と言っても、穴埋め式なので可読性(コードの読みやすさ)が良くなります。

業務処理のプログラミングでは、フォーマットを指定した文字列作成は日常的によく行います。そこで、今回は「format()メソッドの使い方」を「書式指定の方法」と一緒に説明します。

なお、今回はPython3ならばどのバージョンでも使えるformat()メソッドについて説明しますが、Python3.6以上に限定できるのであればf文字列の方が直感的で使いやすいです。f文字列については以下の記事をご覧ください。

Python3.6から、「f文字列(フォーマット済み文字列リテラル:f-string)」が追加されました。 f文字列とは、クウォートで囲んだ文字列の前にfまたはFを付けたもので、その中に波かっこ…
本記事の目次

以下では、Python3.1以上を対象に説明します。

format()メソッドの使い方

以下のように文字列の中に、波かっこ{}で囲まれた「置換フィールド」を埋め込み、format( )メソッドの引数で{}の部分を置換します。

>>> line = "{0}さんの身長は{1}cm、体重は{2}kgです。".format("山田", 190, 105.3)
>>> print(line)
山田さんの身長は190cm、体重は105.3kgです。

つまり、format( )のかっこ内の引数に、format( {0}の値, {1}の値, {2}の値 )のように置換したい値を指定します。引数は左から順番にゼロから始まる番号(インデックス番号)に対応します。

"{0}さんの身長は{1}cm、体重は{2}kgです。"

{0} <= "山田"
{1} <= 190
{2} <= 105.3

置換はインデックス番号の対応で行われるので、以下のように同じ値を複数埋め込めます。

>>> line = "{0}さんの身長は{1}cmです。{0}さんの体重は{2}kgです。".format("山田", 190, 105.3)
>>> print(line)
山田さんの身長は190cmです。山田さんの体重は105.3kgです。

単純に左から順に一対一になっている場合は、以下のようにインデックス番号を省略できます。

# インデックス番号を省略した場合
>>> line = "{}さんの身長は{}cm、体重は{}kgです。".format("山田", 190, 105.3)
>>> print(line)
山田さんの身長は190cm、体重は105.3kgです。
format()メソッドの公式ドキュメントは以下で確認できます。
str.format() -文字列メソッド(Python公式ドキュメント)

書式指定の方法

小数点の桁数を合わせたいなど、書式を指定したい場合は、以下のようにインデックス番号の右にコロン:に続けて指定できます。

{インデックス番号:書式指定}

例えば、身長と体重は小数点以下1桁で統一して表示する場合は以下のようになります。

>>> line = "{0}さんの身長は{1:.1f}cm、体重は{2:.1f}kgです。".format("山田", 190, 105.3)
>>> print(line)
山田さんの身長は190.0cm、体重は105.3kgです。

.1fの部分は、「.1が下1桁」、「fが小数点タイプ」で表示することを意味します。

このようにコロン:の後に、規則に従い順序通りに書式を指定します。以下は、おもな書式指定をすべて使用した例です。

string format

この書式指定を実行すると次のようになります。

>>> "{0:<20,.3f}".format(12345.67)
'12,345.670          '

# インデックス番号は省略できる
>>> "{:<20,.3f}".format(12345.67)
'12,345.670          '

以下に各書式指定の方法について説明します。なお、書式指定の部分だけを見やすくするために、以降では"{:<20,.3f}"のようにインデックス番号を省略した書き方を用います

型(タイプ)の指定

一般によく用いる型だけを以下の表にまとめました。

記号 型(タイプ) 備考
s 文字列 これがデフォルトなので、通常は省略する。
d 整数(10進数) 2進数はb、16進数はxまたはX
eまたはE 浮動小数点数(指数表記) 大文字(E)の場合は指数表記にeでなくEが使われる。
fまたはF 浮動小数点数(小数点表記) 大文字(F)の場合はnanがNAN、infがINFと表示される。

その他にも、汎用フォーマットなどがありますが、ここでは説明しません。必要な場合は、下記のサイトをご覧ください。

string — 一般的な文字列操作(Python公式ドキュメント)

小数点以下の桁数(precison)の指定

「小数点以下?桁」を指定するには、{:.?f}のようにピリオド.の後に整数で桁数を指定します。

>>> "{:.1f}".format(0.01)
'0.0'
>>> "{:.2f}".format(0.01)
'0.01'
>>> "{:.5f}".format(0.01)
'0.01000'

指数表記の場合は以下のようeまたはEを用います。

>>> "{:.1e}".format(0.01)
'1.0e-02'
>>> "{:.2e}".format(0.01)
'1.00e-02'
>>> "{:.5e}".format(0.01)
'1.00000e-02'
>>> "{:.5E}".format(0.01)
'1.00000E-02'

また、この桁数指定を文字列型に使用すると、文字数を最大何文字使用するかを指定できます。

>>> "{:.2}".format("abcde")
'ab'
>>> "{:.3}".format("abcde")
'abc'
>>> "{:.7}".format("abcde")
'abcde'

なお、当然ですがこの桁数指定(precision)は、整数型(d)には使用できません

最小幅(width)の指定

最小幅は、桁数指定の前で指定します。最小幅とは「これ以上狭くならない幅」のことであり、列の幅を揃えたい場合などに利用できます。最小幅に足りない部分は空白(スペース)で埋められます。

以下の浮動小数点数型の例で、{:3.5f}では幅に3を指定していますが、データの0.01.5fで小数点以下5桁まで表示されるので0.01000と幅は7になります。

このようにデータの表示が最小幅に足りている場合は、データの部分は削られることなくそのまま表示されます。一方、{:10.5f}で最小幅を10に指定すると、データ部分の幅は3足りないので、左側を3つの空白(スペース)で埋めます。

>>> "{:3.5f}".format(0.01)
'0.01000'
>>> "{:10.5f}".format(0.01)
'   0.01000'
>>> "{:20.5f}".format(0.01)
'             0.01000'

文字列型の場合も同様に指定した最小幅に足りない場合に、空白で埋められます。ただし、文字列型では右側を空白で埋めます。

>>> "{:2}".format("abcde")
'abcde'
>>> "{:10}".format("abcde")
'abcde     '
>>> "{:20}".format("abcde")
'abcde               '

整数型の場合は以下のようになります。整数型は数値なので、浮動小数点数型と同様に最小幅に足りない場合は左側を空白で埋めます。

>>> "{:2d}".format(100)
'100'
>>> "{:10d}".format(100)
'       100'
>>> "{:20d}".format(100)
'                 100'

上記のように空白で埋められるのは、あくまでも最小幅に足りていない場合だけです。以下のようにデータの表示が最小幅に足りている場合は、そのまま表示されることに気をつけてください。

>>> "{:3d}".format(12345)
'12345'

文字寄せ・パディング

デフォルトの配置は数値は右寄せ、文字列は左寄せです。文字列を右詰めしたい場合は、頭に>を付けます。

>>> "{:>20}".format("abcde")
'               abcde'

空白部分を任意の文字で埋めたい場合は、>の前に文字(1文字)を指定します。

>>> "{:*>20}".format("abcde")
'***************abcde'

数値の空白部分をゼロで埋めたい(ゼロパディング)場合には、最小幅の頭に0を付けるだけで出来ます。

>>> "{:02d}".format(100)
'100'
>>> "{:010d}".format(100)
'0000000100'
>>> "{:020d}".format(100)
'00000000000000000100'

置換フィールドをキーワードで指定する方法

置換フィールドはインデックス番号以外にキーワードを用いて指定することもできます。

以下のように文字列の中に{キーワード}を埋め込み、format()のかっこの中にキーワード=置換する値を入力すると{キーワード}の部分を置換してくれます。

>>> line = "{name}さんの身長は{height}cm、体重は{weight}kgです。".format(name="山田", height=190, weight=105.3)
>>> print(line)
山田さんの身長は190cm、体重は105.3kgです。

文字列が短い場合はコードが見づらくなるので、一般にはあまり使われません。しかし、定型文のような文章のプレースホルダーに使うと意味が分かりやすくなるので便利です。例えば、以下のようなメール本文の作成などに使うことができます。

>>> mail_body_temp = """{company}
{name} 様

いつもお世話になっております。
この度弊社にてセミナーを行いますので、ご案内させていただきます。
ぜひご参加をお待ちしております。
"""
>>> mail_body = mail_body_temp.format(company="パイソン株式会社", name="山田太郎")
>>> print(mail_body)
パイソン株式会社
山田太郎 様

いつもお世話になっております。
この度弊社にてセミナーを行いますので、ご案内させていただきます。
ぜひご参加をお待ちしております。