Symfoware

Symfowareについての考察blog

Python SafeConfigParserでini形式の設定ファイルの読み書き

データベースの接続文字列など、ソースに直接記載せず
設定ファイルに追い出したいと思うのが人情です。

自分で設定ファイルを解析するのは面倒なので、いい方法を探してみます。


SafeConfigParser



ちゃんと標準で読み込み機能が用意されていました。
ConfigParser — 設定ファイルの構文解析器

読み込む設定ファイルのレイアウトは以下の通り。

・setting.cfg(名前は任意です)


[Section1]

host = localhost
database = symfoware
port = 2041
timeout = 0.5
autoclose = true




Windowsのiniファイルと似た感じですね。

[セクション名]で、分類。
項目名 = 値で設定内容を記載します。


このsetting.cfgを読み込むサンプルはこんな感じになりました。


  1. import ConfigParser
  2. config = ConfigParser.SafeConfigParser()
  3. config.read('setting.cfg')
  4. # セクション名、キー名を指定して値を取得
  5. print config.get('Section1', 'host')
  6. print config.get('Section1', 'database')
  7. print config.getint('Section1', 'port')
  8. print config.getfloat('Section1', 'timeout')
  9. print config.getboolean('Section1', 'autoclose')



config.readで設定ファイルを読み込み。
config.get(セクション名, 項目名)で値の取得が行えます。

また、値のデータ型により、getint、getfloat、getbooleanといった
メソッドも用意されており、型変換して値を取得してくれます。
当然、文字列型の値に対してgetintするとエラーになります。

プログラムを実行すると、こんな表示になりました。


$ python sample.py
localhost
symfoware
2041
0.5
True




ちゃんと値が取得できていますね。





デフォルト値の指定



例えば、hostの項目が省略されていたらlocalhostをデフォルト値として
採用したいということがあると思います。

そんな時は、インスタンス生成時に予めデフォルト値を指定しておきます。


・setting.cfg


[Section1]

timeout = 0.5
autoclose = true


[Section2]

host = db-sb
database = mariadb
port = 3306
timeout = 1.5
autoclose = false





プログラムはこうなりました。


  1. import ConfigParser
  2. default_config = {
  3.     'host' : 'localhost',
  4.     'database' : 'symfoware',
  5.     'port' : '2041'
  6. }
  7. config = ConfigParser.SafeConfigParser(default_config)
  8. config.read('setting.cfg')
  9. # セクション名、キー名を指定して値を取得
  10. print config.get('Section1', 'host')
  11. print config.get('Section1', 'database')
  12. print config.getint('Section1', 'port')
  13. print config.getfloat('Section1', 'timeout')
  14. print config.getboolean('Section1', 'autoclose')
  15. print '-' * 10
  16. print config.get('Section2', 'host')
  17. print config.get('Section2', 'database')
  18. print config.getint('Section2', 'port')
  19. print config.getfloat('Section2', 'timeout')
  20. print config.getboolean('Section2', 'autoclose')




注意点として、getintで取得する項目のデフォルト値も文字列で指定することです。
int型で辞書に登録していると


AttributeError: 'int' object has no attribute 'find'



というエラーが発生します。


実行してみると、狙い通りの結果が得られました。


$ python sample.py
localhost
symfoware
2041
0.5
True
----------
db-sb
mariadb
3306
1.5
False







文字列置換機能



設定ファイル内の値を使用して、文字列の置換を行うことができます。

・setting.cfg


[Section1]

timeout = 0.5
autoclose = true


[Section2]

host = db-sb
database = mariadb
port = 3306
timeout = 1.5
autoclose = false
connect_str = %(host)s:%(database)s:%(port)s:notmysql





プログラムは以下の通り。


import ConfigParser

default_config = {
    'host' : 'localhost',
    'database' : 'symfoware',
    'port' : '2041',
    'connect_str' : '%(host)s:%(database)s:%(port)s'
}

config = ConfigParser.SafeConfigParser(default_config)
config.read('setting.cfg')

# セクション名、キー名を指定して値を取得
print config.get('Section1', 'host')
print config.get('Section1', 'database')
print config.getint('Section1', 'port')
print config.getfloat('Section1', 'timeout')
print config.getboolean('Section1', 'autoclose')
print config.get('Section1', 'connect_str')

print '-' * 10

print config.get('Section2', 'host')
print config.get('Section2', 'database')
print config.getint('Section2', 'port')
print config.getfloat('Section2', 'timeout')
print config.getboolean('Section2', 'autoclose')
print config.get('Section2', 'connect_str')




実行してみると、フォーマットルールに従い置換された状態の文字が取得できます。


$ python sample.py
localhost
symfoware
2041
0.5
True
localhost:symfoware:2041
----------
db-sb
mariadb
3306
1.5
False
db-sb:mariadb:3306:notmysql





自動的に変換してほしくない場合は、第三引数に「1」を指定します。


  1. print config.get('Section1', 'connect_str', 1)
  2. print config.get('Section2', 'connect_str', 1)




$ python sample.py
%(host)s:%(database)s:%(port)s
%(host)s:%(database)s:%(port)s:notmysql








設定値の保存



設定値を変更して保存してみます。


  1. import ConfigParser
  2. default_config = { 'count' : '0' }
  3. config = ConfigParser.SafeConfigParser(default_config)
  4. config.read('setting.cfg')
  5. count = config.getint('Section1', 'count')
  6. print count
  7. # 値をインクリメントして保存
  8. count += 1
  9. config.set('Section1', 'count', str(count))
  10. with open('setting.cfg', 'wb') as f:
  11.     config.write(f)




狙い通り、実行するたびインクリメントされていきます。


$ python sample.py
0
$ python sample.py
1
$ python sample.py
2
$ python sample.py
3
$ python sample.py
4
$ python sample.py
5
$ python sample.py
6




setting.cfgはこんな感じで保存されていました。


[DEFAULT]
count = 0

[Section1]
count = 7


関連記事

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2015/01/18(日) 17:49:46|
  2. Python
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集
<<Pythonで辞書型のオブジェクトをキーワード引数として関数に渡す | ホーム | Python 実行しているスクリプトの絶対パスを取得する>>

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://symfoware.blog68.fc2.com/tb.php/1589-95b8fd97
この記事にトラックバックする(FC2ブログユーザー)