[Python]書式指定 + 引数の展開で文字列を見やすく扱う

文字列を動的に生成する上で覚えておきたい書式指定についてまとめました。

書式指定の基本

{}を囲った文字列 + .format()で{}内を指定できる

'Sample {}'.format('code')

# Sample code

複数の{}は順番に指定する

'{} {} {}'.format('I', 'like', 'dogs')

# I like dogs

{}内に数字を入れて順番を指定する

'{1} {2} {0}'.format('dogs', 'I', 'like')

# I like dogs

{}内に名前をつければキーワード引数の形で指定できる

'{who} {verb} {object}.'.format(who='I', verb='like', object='dogs')

# I like dogs

.formatはstring型のオブジェクトで使えるので、当然文字列を代入して使うこともできます。

message = '''Hi {receipant},

Thank you for ordering {item}.
It will take {days} days to ship.

{sender}
'''

print(message.format(receipant='Yamada', item='a desk', days=3, sender='Sato'))

# Hi Yamada,
#
# Thank you for ordering a desk.
# It will take 3 days to ship.
#
# Sato

辞書を渡して展開したい

dict = {
    'receipant' : 'Yamada',
    'item'      : 'a desk',
    'days'      : 3,
    'sender'    : 'Sato'
}

print(message.format(**dict))

**dict ?

「引数の展開」というもので、
*(アスタリスク)を2個つけて辞書型のオブジェクトを渡すと、中身を展開して引数に渡すことができます。

キーワード可変長引数とは別の話なので混同しないよう注意。

setting = {
    'year' : 2019,
    'month' : 10,
    'day' : 1
}
datetime.datetime(**setting)

# datetime.datetime(2019, 10, 1, 0, 0)

位置引数の場合

位置引数の場合、*listと指定すると、リストを展開して引数にできます。

setting = [2019, 10, 1]
datetime.datetime(*setting)

# datetime.datetime(2019, 10, 1, 0, 0)

まとめ

文字列の動的生成では、+を使っていましたが、
int型をそのまま入れるとTypeErrorになるため、
都度str()で変換するなど地味に面倒でした。
デバッグやログ用出力という目的であれば、このへんを柔軟にできるのはありがたいです。

ちなみに、

'{name:s} {number:d} {float:f}'.format(name='text', number=10,float=0.5)

# text 10 0.500000

のように、型を指定することもできます。

可変長引数と引数の展開については
[Python]可変長引数と引数展開でコードをスッキリさせるでも取り上げています。

参考