Python configparserのwrite()とは?設定ファイルを書き出す方法

write()は、設定内容をINI形式でファイルに書き出すメソッドです。

設定の初期ファイルを生成したり、アプリ内で変更した設定を保存したりするのに使います。


write()の基本

import configparser

c = configparser.ConfigParser()
c["DEFAULT"] = {"timeout": "30"}
c["server"] = {"host": "localhost", "port": "8080"}
c["server"]["debug"] = "yes"

with open("out.ini", "w", encoding="utf-8") as f:
    c.write(f)

print(open("out.ini", encoding="utf-8").read())

実行結果:

[DEFAULT]
timeout = 30

[server]
host = localhost
port = 8080
debug = yes

引数はファイル名ではなく、開いたファイルオブジェクトです。

c.write("out.ini")とは書けません。open()してから渡してください。


値は文字列でなければならない

c = configparser.ConfigParser()
c["a"] = {"x": "1"}

c["a"]["n"] = 8080

実行結果:

TypeError: option values must be strings

数値をそのまま代入できません。str()で変換してください。

c["a"]["n"] = str(8080)

ただしセクションごと辞書で代入した場合は自動変換されます。

c["b"] = {"n": 8080}
print(repr(c["b"]["n"]))

実行結果:

'8080'

書き方によって挙動が変わるため、最初からstr()で統一するのが安全です。


コメントは保存されない

これが最大の注意点です。

次のようなファイルを読んで、そのまま書き出してみます。

# 先頭コメント
[s]
; 別のコメント
a = 1
c = configparser.ConfigParser()
c.read("cm.ini")

with open("cm.ini", "w") as f:
    c.write(f)

結果はこうなります。

[s]
a = 1

コメントがすべて消えました。

configparserはコメントを読み飛ばしており、記憶していません。

そのため人が手で書いた設定ファイルを読み込んで上書き保存すると、説明がすべて失われます。

  • 人が編集するファイルはプログラムから上書きしない
  • プログラムが書くファイルは専用のものを分ける

コメントを残したまま編集したい場合は、configobjなど外部ライブラリが必要です。


書式も正規化される

元のファイルがこうでも、

[s]
a:1
b=2

書き出すとこうなります。

[s]
a = 1
b = 2

区切り文字は=に、前後に空白が入った形に統一されます。

空白を詰めたい場合は指定できます。

c.write(f, space_around_delimiters=False)

実行結果:

[s]
a=1
b=2

並び順とDEFAULT

c = configparser.ConfigParser()
c["s"] = {"a": "1"}
c["DEFAULT"] = {"t": "30"}

with open("o.ini", "w") as f:
    c.write(f)

実行結果:

[DEFAULT]
t = 30

[s]
a = 1

[DEFAULT]は必ず先頭に置かれます。あとから追加しても同じです。

それ以外のセクションとキーは追加した順に並びます。アルファベット順にはなりません。


%を含む値の扱い

c = configparser.ConfigParser()
c["s"] = {"p": "50%%"}

with open("p.ini", "w") as f:
    c.write(f)

print(c["s"]["p"])

実行結果:

50%

ファイルにはp = 50%%と書かれ、読み出すと50%になります。

configparserは%を変数展開の記号として使うため、文字としての%は%%と二重にする必要があります。

パスワードやURLに%が入る場合は、展開機能を無効にするほうが簡単です。

c = configparser.ConfigParser(interpolation=None)

これで%をそのまま扱えます。


安全に上書きする

書き込み中にプログラムが落ちると、設定ファイルが壊れた状態で残ります。

import os
import configparser

tmp = "config.ini.tmp"

with open(tmp, "w", encoding="utf-8") as f:
    c.write(f)

os.replace(tmp, "config.ini")

一時ファイルに書いてから置き換えます。os.replace()は同じディスク内なら中断されない操作なので、中途半端なファイルが残りません。


write()のまとめ

  • 引数はファイルオブジェクト(ファイル名ではない)
  • 値は文字列——直接代入ではTypeError
  • コメントはすべて失われる
  • 区切り文字や空白は正規化される
  • [DEFAULT]は常に先頭、他は追加順
  • %は%%——扱うならinterpolation=None
  • 上書きは一時ファイル+os.replace()

あわせて読みたい

プログラミング学習に興味がある方は、まずは無料体験会へ

無料体験会・お申し込みはこちら