Python で INI / 設定ファイルを読み書きする(configparser)
INI ファイルは Windows の設定ファイルとして広まったフォーマットで、セクションとキー・バリューのシンプルな構造を持つ。Python では標準ライブラリの configparser モジュールを使って読み書きできるため、外部ライブラリのインストールが不要だ。
INI ファイルの基本構造
INI ファイルは [セクション名] でセクションを区切り、その中に キー = 値 のペアを並べる。
[database]
host = localhost
port = 5432
name = myapp
[logging]
level = DEBUG
file = app.log値はすべて文字列として扱われる。YAML や TOML と異なり、型の自動変換は行われない。数値や真偽値が必要な場合は、読み込み後に明示的に変換する必要がある。
INI ファイルを読み込む
configparser.ConfigParser を使って INI ファイルを読み込む基本パターンを見てみよう。
import configparser
config = configparser.ConfigParser()
config.read("config.ini", encoding="utf-8")
# セクションの一覧
print(config.sections()) # ['database', 'logging']
# 値の取得
host = config["database"]["host"]
port = config["database"]["port"]
print(f"{host}:{port}") # localhost:5432
config.read() はファイルが存在しない場合でもエラーを出さず、空の設定として扱われる。ファイルの存在を保証したい場合は、事前に os.path.exists() で確認するか、read_file() を使って明示的にファイルオブジェクトを渡すとよい。
import configparser
config = configparser.ConfigParser()
# ファイルオブジェクトを渡す方法(ファイルがなければ例外が出る)
with open("config.ini", encoding="utf-8") as f:
config.read_file(f)
型変換メソッド
configparser の値はすべて文字列だが、型変換用のメソッドが用意されている。
import configparser
config = configparser.ConfigParser()
config.read_string("""
[server]
host = 0.0.0.0
port = 8080
debug = true
timeout = 30.5
""")
# 文字列(デフォルト)
host = config.get("server", "host")
# 整数
port = config.getint("server", "port")
# 真偽値
debug = config.getboolean("server", "debug")
# 浮動小数点
timeout = config.getfloat("server", "timeout")
print(f"{host}:{port}, debug={debug}, timeout={timeout}")
# 0.0.0.0:8080, debug=True, timeout=30.5
getboolean() が真と判定する値は 1, yes, true, on で、偽と判定するのは 0, no, false, off だ。大文字小文字は区別されない。
| メソッド | 戻り値の型 | 用途 |
|---|---|---|
| get() | str | 文字列として取得 |
| getint() | int | 整数として取得 |
| getfloat() | float | 浮動小数点として取得 |
| getboolean() | bool | 真偽値として取得 |
デフォルト値とフォールバック
キーが存在しない場合に備え、fallback パラメータでデフォルト値を指定できる。
import configparser
config = configparser.ConfigParser()
config.read_string("""
[server]
host = localhost
""")
# キーがなければ fallback が返る
port = config.getint("server", "port", fallback=3000)
debug = config.getboolean("server", "debug", fallback=False)
print(port) # 3000
print(debug) # False
また、ConfigParser には DEFAULT セクションという特殊なセクションがあり、ここに書いた値はすべてのセクションで共有される。
import configparser
config = configparser.ConfigParser()
config.read_string("""
[DEFAULT]
timeout = 30
retry = 3
[database]
host = localhost
[cache]
host = redis-server
""")
# DEFAULT の値がどちらのセクションでも取得できる
print(config.getint("database", "timeout")) # 30
print(config.getint("cache", "retry")) # 3
DEFAULT セクションの値はあくまでフォールバックであり、各セクションで同じキーを定義すれば上書きされる。設定ファイル全体で共通のデフォルト値を定義したいときに有効な仕組みだ。
INI ファイルに書き込む
ConfigParser で構築した設定をファイルに書き出すには write() メソッドを使う。
import configparser
config = configparser.ConfigParser()
config["server"] = {
"host": "0.0.0.0",
"port": "8080",
"debug": "false",
}
config["database"] = {
"host": "localhost",
"port": "5432",
"name": "myapp",
}
with open("output.ini", "w", encoding="utf-8") as f:
config.write(f)
出力結果は以下のようになる。
[server]
host = 0.0.0.0
port = 8080
debug = false
[database]
host = localhost
port = 5432
name = myapp値はすべて文字列として渡す点に注意しよう。数値や真偽値も文字列に変換してからセットする必要がある。
設定の変更と保存
既存の INI ファイルを読み込み、一部を変更して書き戻すパターンもよく使われる。
import configparser
config = configparser.ConfigParser()
config.read("config.ini", encoding="utf-8")
# 値の変更
config["server"]["port"] = "9090"
# セクションの追加
config["newfeature"] = {
"enabled": "true",
"version": "2",
}
# キーの削除
config.remove_option("logging", "file")
# セクションの削除
# config.remove_section("obsolete")
with open("config.ini", "w", encoding="utf-8") as f:
config.write(f)
読み込みと書き込みで同じファイルを指定する場合、書き込み時にファイル全体が上書きされる。コメントは保持されないため、コメント付きの INI ファイルを編集する用途には向いていない。
configparser の制限
configparser はシンプルで使いやすい反面、いくつかの制限がある。
セクション内にサブセクションを作れない。深い構造の設定には YAML や TOML が適している。
型変換メソッドはあるが、リストや辞書を直接格納する方法がない。カンマ区切りの文字列を split() で分割するといった工夫が必要になる。
読み込み時にコメントは破棄されるため、write() で書き戻すとコメントが消える。
リスト的な値を扱いたい場合は、カンマ区切りで工夫する方法が現実的だ。
import configparser
config = configparser.ConfigParser()
config.read_string("""
[app]
allowed_hosts = localhost, 127.0.0.1, example.com
""")
# カンマ区切りをリストに変換
hosts = [h.strip() for h in config.get("app", "allowed_hosts").split(",")]
print(hosts) # ['localhost', '127.0.0.1', 'example.com']
どのフォーマットを選ぶべきか
INI、YAML、TOML にはそれぞれ異なる特徴がある。プロジェクトの要件に応じて選択しよう。
標準ライブラリだけで完結し、構造がフラットでわかりやすい。小規模なアプリケーションやレガシーシステムの設定に向いている
ネスト構造やリスト、型付きの値を自然に表現できる。モダンなプロジェクトではこちらを選ぶケースが増えている
既存のプロジェクトで INI ファイルが使われている場合は configparser を使えば十分だ。新規プロジェクトで設定ファイルのフォーマットを選べるなら、型の明確さやエコシステムとの統合の観点から TOML を検討する価値がある。ただし、外部依存なしで動作する configparser の手軽さは、小さなスクリプトやユーティリティでは今でも大きなメリットになる。