見出し画像

いろいろな言語での書式指定子たち#5 - python

pythonを覚えたのはもうかなり昔になりましたし、当時のpythonはバージョン2になった頃なので、今とはいろいろな違いがあります。その頃は、書式指定付きの入出力というものは特別に用意されているわけではなく、文字列に対する % 演算子という便利なものがあっただけでした。

この演算子は対象文字列の中にある % で始まる文字列に対して、値またはタプルの値を埋め込むことが出来るというものです。

s = "name:%s" % "John"
t = "id=%d,value=%d" % (1, 3500)

これで

>>> s
'name:John'
>>> t
'id=1,value=3500'

となる訳です。

もちろん、この結果をprintすればC言語のprintfと同じように使えるわけです。この%演算子による処理は「古いもの」として今では推奨されていないようで、今は format関数を使うことになっているようです。細かい部分は触れませんが、formatにある書式の中には % で使えないものがあったり微妙な違いがあるものもあるようです。

書式化演算子%を使った文字列の書式設定(printf形式の書式化)

%に続き変換すべき型を指定するのはC言語などと似ていて %d や %x そして %e などが使えます。python はオブジェクトを扱えますから文字列として表現するにはそのためのメソッドを呼ぶ形で %s などは実装されています(%sはオブジェクトのstr()メソッドを呼ぶ)。なおpythonの整数型は符号なしという型が無いので注意が必要です。%uもあるのですが%dと同じですし、%xを使っても負の値は負で表されます。

>>> "%u" % -12
'-12'
>>> "%x" % -12
'-c'

変換元の書式文字列と%演算子のあとに書く変数の対応は、何も書かなければ、やはりC言語と同じように出現順序でタプルと結び付けられますが、書式の%のすぐ後ろに()で囲った名前(マップキー)を書くことで、%演算子のあとに辞書型のオブジェクトを書いて、そのキーで対応する値を指定することもできます。

>>> "10進で%(dc)d, 16進で%(hx)x" % { "hx":12, "dc":14 }
'10進で14, 16進でc'

そしてフラグとしては”0”をつければ指定した桁になるまで左側の0を補いますし、”-”で左寄せ(この指定がなければ右寄せ)になります。便利なのが%の次に”#”を置くことで16進数であれば0xを8進数であれば0を先頭につけるので、一般的な16進または8進表記に成ります。そして続いて0以外の数字をかけばそれば最小幅として解釈されるのですが、”*”を指定すると%演算子で与える値を最小幅として解釈してくれたりします(書式に登場する%の数とタプルの値の数は合わなくなる)。

>>> "%d,%*d" % (12, 2, 8)
'12, 8'

精度、つまり小数の小数点以下の桁数は、他の処理系と同じように”.”に続いて数値を指定します。この指定にも”*”は使えます。

>>> "%f,%.3f,%.*f" % (1/3, 1/3, 2, 1/3)
'0.333333,0.333,0.33'

“*”は便利なのかもしれませんが、使い所に悩みます。


それから簡易な書式指定としてf-stringという方法があります。

>>> f'{"abc"},{"def"}!'
'abc,def!'

もちろん”で囲った文字列リテラルの部分は変数であってもOKです。文字列の前にfを付ければ{}で囲んだ部分を埋め込んでくれます。実にシンプル。

Python 文字列の書式指定とフォーマット


そして文字列に対する format メソッドを使うのが最近の流儀です。

書式化演算子%とformatメソッドを比較してみた〜構文と書式設定

埋め込む場所を指定する文字列に対して format メソッドを呼び出し、その引き数で渡した値を埋め込んでくれます。埋め込む場所は”{}”で指定します(”%”ではありません)。

>>> "{}".format(32)
'32'

“{}”の中に数字を書けば、それはformatの何番目の引き数(最初の引き数であれば0)を埋め込むかの指定になり、書式を指定する場合は”:”に続けて指定します。最初の記号は文字寄せの指定で、”<”で左寄せ、”>”で右寄せになります。指定しなければ値が数値の場合は右寄せ、文字列の場合は左寄せになります。続けて”0”を書けばゼロパディングの指定で、さらに数値を続けて、こちらは最小幅です。

>>> "{0:<3}{0:03}".format(12)
'12 012'

小数の場合はさらに小数点”.”を置いて数字を書くと小数点以下の桁数を指定できます。

>>> "{:.3}".format(1/3)
'0.333'

この小数点の前の位置に”,”を入れると3桁ごとのカンマ区切りも指定できます。

>>> "{:,}".format(12345)
'12,345'

最後の文字として型を指定することも出来ますが、省略すると文字列”s”とみなされ適切な書式が選択されます。10進の整数であれば”d”、8進は”o”、16進は”x”(または”X”)ですが、”b”を書いて2進で表現することも出来ます(これは%演算子にはない)。そして”e”や”f”ももちろんあります。

>>> "{:,.3}".format(12345.67)
'1.23e+04'
>>> "{:,.3f}".format(12345.67)
'12,345.670'

小数の値を整数で表示しようとしても変換されるのではなくエラーとなります。

>>> "{:d}".format(12345.67)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: Unknown format code 'd' for object of type 'float'
>>> "{:d}".format(int(12345.67))
'12345'

Python 書式指定一覧

%演算子と同じように”{}”の先頭のインデックスの数字の代わりに名前を書くと、formatメソッドの名前付き引き数の名前を使うことも出来ます。

>>> "{value}".format(value=12345.67)
'12345.67'

[Python入門]文字列の書式指定

ここまでは素直な使い方なんですが、寄せには左右だけではなく中央寄せもあったり、空白以外の文字を補うことも出来ます。

>>> "{:^10}".format(12)
'    12    '
>> >"{:.^10}".format(12)
'....12....'

多彩な機能があって、もうこれで充分と思うかもしれませんが、pythonはオブジェクトな言語です。stringクラスにはfomatterクラスがあり、このメソッドをオーバライドすることで、formatメソッドをカスタマイズすることも出来ます(これが%演算子との大きな違い)。まあカスタマイズを書くのは簡単では無いですが、日時などロケールが絡むと必要性は出てくるのかもしれません。詳しいことはご本家のドキュメントを確認してください。

string --- 一般的な文字列操作

書式設定文字列の文法を定義して、そこからカスタマイズできるのが最近の「正しい」流儀なのでしょう。そして使いこなすにはオブジェクトを文字列で表現する repr メソッドを慎重に設計することが肝要ですね。


おまけ

以下の記事がとてもコンパクトに python の特徴をまとめています。もっとも少しは python を知っていないとワケワカですけどね。

【図解】Python基礎64選


ヘッダ画像は、Copilotで作りました。

#プログラミング言語 #書式 #python #パーセント演算子 #format #f文字列

この記事が気に入ったらサポートをしてみませんか?