[python3]ヒアドキュメントのTextwrap.dedent() が効かない
記事カテゴリ テクノロジー
投稿日: 2020年08月18日
Jump to heading 事象
ヒアドキュメントの余計なインデントを無効化するために、Textwrap.dedent()を使用したが、
想定どおりに無効化されない。
Jump to heading 実行環境
root@f939e639fd93:~# python --version
Python 3.8.5
Jump to heading 期待する動作
test.py
def write_profile():
profile_file_name = 'profile.txt'
my_profile = """My name is {my_name}.
I'm {age} years old.
I like to {hobby}.""".format(my_name="roppong", age="31", hobby="run outside")
with open(profile_file_name, 'w') as f:
f.write(my_profile)
write_profile()
ヒアドキュメントで定義した文字列をファイルに書き込んだ結果、下記ファイルが作成されることを期待していた。
root@f939e639fd93:~# python test.py
root@f939e639fd93:~# cat profile.txt
My name is roppong.
I'm 31 years old.
I like to run outside.
しかし、実際には、下記のような出力となった。
root@f939e639fd93:~# python test.py
root@f939e639fd93:~# cat profile.txt
My name is roppong.
I'm 31 years old.
I like to run outside.root@f939e639fd93:~#
pythonファイルのインデントがそのままファイルに反映されている。
しかし、スクリプト上のインデントを解除すると、ソースコードの可読性が落ちてしまうためそれは避けたい。
インデントを無効化するために、Textwrap.dedent()を使用すればいいと分かった。
from textwrap import dedent
を追加して、インデントを無効化したい文字列をdedent()に渡す。
Jump to heading 修正後1
test.py
from textwrap import dedent
def write_profile():
profile_file_name = 'profile.txt'
my_profile = """My name is {my_name}.
I'm {age} years old.
I like to {hobby}.""".format(my_name="roppong", age="31", hobby="run outside")
with open(profile_file_name, 'w') as f:
f.write(dedent(my_profile))
write_profile()
Jump to heading 結果1
root@f939e639fd93:~# python test.py
root@f939e639fd93:~# cat profile.txt
My name is roppong.
I'm 31 years old.
I like to run outside.root@f939e639fd93:~#
効かない。「dedent does not work」でググって、下記ページを見つける。
Textwrap.dedent() does not work
dedentの仕様上、2行目以降のインデントは、1行目のインデントの情報を引き継ぐらしい。
ということで、ヒアドキュメントのクォート3つの後に、pythonのインデント2つ分(空白8つ)を入れる。
Jump to heading 解決策
Jump to heading 修正後2
test.py
from textwrap import dedent
def write_profile():
profile_file_name = 'profile.txt'
my_profile = """ My name is {my_name}.
I'm {age} years old.
I like to {hobby}.
""".format(my_name="roppong", age="31", hobby="run outside")
with open(profile_file_name, 'w') as f:
f.write(dedent(my_profile))
write_profile()
これで、もともと欲しかったファイルを得ることができた。