Pythonでアプリ設定を保存したい
そういう時に候補に挙がるのがINIファイル
- テキストだから編集しやすいし、
- セクションごとに分けられるし、
- アプリ設定を読み書きしやすい
こういう利点があるから便利です。
そしてPythonでINIファイルを扱うには、
「configparser」
このモジュールがとても重宝します。
しかも標準ライブラリだから初めから使用可能です。
この使い方・コード例をまとめたいと思います。
このページの目次
初めにINIフォーマットの概要とか文法について
文法っていうほど複雑ではないですが……
そもそも、INIはWindows用データ形式でした。
▼ 最も単純なINIファイルの例
1 2 3 4 5 |
[DEFAULT] hoge = 1234 [main] hoge = 1234 |
このようにセクションは [セクション名] で表し、その下に hoge = 1234 のようにキー・値をイコールで区切ってオプションを並べる形式です。
▼ 厳密な仕様はない?けど、より詳しく
参考 : INIファイル - Wikipedia
JSONなんかと比べると本当にシンプルな形式だし、誰にとっても編集しやすいのが利点です。便利だからWindows以外でも使われるようになりました。
ちなみに [DEFAULT] がデフォルトセクションです。
INIフォーマットの概要はこんな感じ
初めにconfigparserでできること・機能について
このconfigparserモジュールの機能について。
▼ 大まかに書くなら次のことができる
- ファイルからINI形式を解析
- INIのセクション/オプション読込
- INIのセクション/オプション追加
- ファイルにINI形式を書き込む
ただしconfigparserは以下の点はカバーしてません。
▼ 次のことはやってくれない
- iniファイルが存在するかのチェック
- 存在しない場合にはファイル作成
だから上記2点だけは自前で行う必要があります。
INIファイルからアプリ設定を読み込みする関数例
それでは具体的なコード例を書いてみます。
ここでは config.ini というファイル名にします。
そのINI設定を読み込む次の関数を作りました。
▼ INIファイルを読み込みしてオプション読み込み
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
import configparser from configparser import ConfigParser def getConfigOption(key, fallback, section=None): """ get INI config option or fallback. Args: key (str): Option key name fallback (str): Option fallback section (str): Section name Returns: str: Option value """ config.read('config.ini') if section is None: ## デフォルトセクションを使用 section = configparser.DEFAULTSECT ## オプション読み込み。ないならfallbackを返す option = config.get(section, key, fallback=fallback) return option |
▼ この関数の使用コード例
1 2 3 4 5 |
## DEFAULTセクションから読み込み self.getConfigOption('hoge', '0000') ## mainセクションから読み込み self.getConfigOption('hoge', '0000', 'main') |
デフォルトセクションは configparser.DEFAULTSECT (値としては 'DEFAULT' )で表されるので、セクションがNoneだったらそれを使用してます。
あとは特に説明することないですね。
INIファイルにアプリ設定を書き込みする関数例
読み込みときたら次は書き込みです。
今度も次のような関数を作ってみました。
▼ INIファイル読み込んでオプション書き込み
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
import configparser from configparser import ConfigParser def setConfigOption(key, value, section=None): """ Set INI config option. Args: key (str): Option key name value (str): Option value section (str): Section name """ config.read('config.ini') if section is None: ## デフォルトセクションを使用 section = configparser.DEFAULTSECT elif not config.has_section(section): ## セクション未定義なら作成 config.add_section(section) ## オプションを追加・設定する config.set(section, key, value) ## 実際のINIファイルに反映させる with open('config.ini', 'w') as f: config.write(f) |
▼ この関数の使用コード例
1 2 3 4 5 |
## DEFAULTセクションに書き込み self.setConfigOption('hoge', '9876') ## mainセクションに書き込み self.setConfigOption('hoge', '9876', 'main') |
セクションが存在するかどうかを config.has_section(section) で調べ、ないなら config.add_section(section) で追加する必要があります。
あとデフォルトセクションが曲者だった……それを config.add_section(section) しようとするとValueErrorが出るため、このような処理を書いています。
あと実際のINIファイル更新も忘れないこと
ファイルへの書き込みは各自で行います。
このconfigparserの留意点。データ型に注意
1点だけconfigparserは注意点があります。
それは次のようにデータを扱ってることです。
- 読み書きするデータは全て文字列型
- データ型を判別するスマートな機能はない
オプション値はすべて文字列で扱われます。
▼ 詳しくは次の解説を参照
Config parsers do not guess datatypes of values in configuration files, always storing them internally as strings. This means that if you need other datatypes, you should convert on your own:
>>> int(topsecret['Port'])
50022
>>> float(topsecret['CompressionLevel'])
9.0
▼ この解説の適当な意訳
ConfigParserは設定ファイル内のオプション値のデータ型を自動判別しません。常に文字列として取り扱います。つまり文字列以外のデータ型が必要なら、各自で変換しないとダメです。
こういう制約があるので注意してください。
数値とかなら '1234' のように文字列での保存しかできないし、取り出すときもint関数などを通して変換してあげる必要があります。
アプリ設定保存に重宝すると思う
ということでconfigparserの使い方でした。
アプリ設定保存に重宝すると思います。
ただしもっと複雑な構成を保存したいなら、
それはJSON・DBとか使う方がいいかもしれません。
そこは各自の用途次第です。