Python

[Python] ConfigParserでiniファイルからリストを取得したい

2020-02-02

ConfigParserでiniファイルからリストを取得したい


ConfigParserでiniファイルからリストを取得したい

PythonのConfigParserを使うと、iniファイルから設定を読み込んで利用することができる。

iniファイルには自由なキーと値を設定できるが、値をリストとして取得したい場合どうすればよいのか

今回はConfigParserでiniファイルからリストを取得する方法について紹介する。

この記事を書いている人


システムエンジニア、AIエンジニアと、IT業界で10年以上働いている中堅。PythonとSQLが得意。

記事を読むメリット

PythonのConfigParserでiniファイルからリストを取得する方法がわかる


iniファイルとは


iniファイルとはその名の通り拡張子が ini となっているファイルである。

ファイル形式としては普通のテキストファイルと同じで、メモ帳のようなテキストエディタで読み書きができる。

ではテキストファイルと何が違うのかというと、使われ方に特徴がある。

iniファイルはプログラムの設定ファイルとして使われる。
iniファイルを用いるメリットとしては、プログラム本体と設定ファイルを切り離すことで、本体のコードには変更を加えずに色々な設定でプログラムを動作させることができる。

INIファイルは構造の単純なテキストファイルであり、設定ファイルのフォーマットとしてよく使われている。INIファイルは主にWindowsで使用するが、他のプラットフォームでも使われる。 INIファイルという名前はこのファイルの一般的な拡張子「.INI」から来ている。


iniファイルをPythonから扱う方法


そんなiniファイルをPythonでも扱いたい場合は ConfigParser を用いる。

まずiniファイルのサンプルとして以下のような sample.ini ファイルを用意する。

[settings]
SETTINGS_01=settings content 01
SETTINGS_02=settings content 02

そしてPythonから ConfigParser を用いてiniファイルを読み込むと、iniファイルの各設定を呼び出すことができる。
第1引数が [settings] に対応するセクションを指定しており、第2引数でキー SETTINGS_01 を指定して対応する値を取得している。

import configparser

config = configparser.ConfigParser()
config.read("sample.ini")

settings_01 = config.get("settings", "SETTINGS_01")
settings_02 = config.get("settings", "SETTINGS_02")
print("settings_01: {}".format(settings_01))
print("settings_02: {}".format(settings_02))

# settings_01: settings content 01
# settings_02: settings content 02


iniファイルからリストを取得したい


Pythonからiniファイルを扱う方法はわかった。
しかしここで新たな疑問が出てくる。

iniファイル中のキーに対応する値としてリストを設定して、Pythonから値を取得する際にlist型として取得できないか

試してみると以下のようになる。

[settings_list]
SETTINGS_03=["content03-1","content03-2","content03-3"]
settings_03 = config.get("settings_list", "SETTINGS_03")
print(settings_03)
print(type(settings_03))

# ["content03-1","content03-2","content03-3"]
# <class 'str'>

複数要素で構成されたlist型で取得したいが、実際に取得できたのは全ての要素が1つの文字列としてつながったstr型。

つまりiniファイルから取得した要素は文字列としてPythonに読み込まれる。

では設定をリストとして持たせて取り込むのは不可能かというと、そうでもない。


evalで取り込む


文字列をコードとして評価する eval() を使うと [] で括られたlist型としてデータを取得することができる。

settings_03_1 = eval(config.get("settings_list", "SETTINGS_03"))
print(settings_03_1)
print(type(settings_03_1))

# ['content03-1', 'content03-2', 'content03-3']
# <class 'list'>

しかし eval() は任意の内容をコードとして評価する為、プログラム製作者の意図から逸脱した悪意あるコードをiniに仕込まれた場合、実行されてしまうという脆弱性をもっている。

なので別の方法も考えてみる。


iniファイルの外でリストを用意して読み込む


設定ファイルのメリットはプログラム本体とは別ファイルとして扱えること。
ではリスト形式の設定を必ずしもiniファイルに持つ必要はない。
リスト形式の設定は csv から読み込めばいい。

やり方としては、iniファイルにはリスト設定を書き込んだcsvファイルのパスを書いておく。

[settings_list]
SETTINGS_03_CSV=SETTINGS_03.csv

そしてリスト設定を書き込んだcsvファイル SETTINGS_03.csv をiniファイルとは別で用意する。

CONTENT
content03-1
content03-2
content03-3

そしてPython側ではiniファイルから読み込んだcsvファイルのパスを、pd.read_csv() で読み込んでしまえばDataFrameもしくはlist型として設定を読み込むことができる。

import pandas as pd

settings_03_csv = config.get("settings_list", "SETTINGS_03_CSV")
print(settings_03_csv)

df_settings_03 = pd.read_csv(settings_03_csv)
print(df_settings_03["CONTENT"].to_list())
print(type(df_settings_03["CONTENT"].to_list()))

# ['content03-1', 'content03-2', 'content03-3']
# <class 'list'>

この方法であれば eval() のように任意のコードを仕込まれる心配は無い。


jsonで読み込む


また eval() の代わりにjsonライブラリの json.loads() を使って読み込むことも可能。

import json

settings_03_1 = json.loads(config.get("settings_list", "SETTINGS_03"))
print(settings_03_1)
print(type(settings_03_1))

# ['content03-1', 'content03-2', 'content03-3']
# <class 'list'>


まとめ


ConfigParserでiniファイルからリストを取得したい場合は、 eval() を利用することでlist型として読み込むこともできるが脆弱性のリスクがある。

eval() の代わりにjsonライブラリの json.loads() を使うか、リストをcsvとして外出しにしてcsvのパスをiniファイルに持たせるかすると良い。

コード


Pythonのコードが出来上がったら次は定期的に実行させる環境に移してコードを実行すると思う。

ランニングコストをかけてネット上に実行環境を作るのもありだが、小型PCを購入してランニングコストを下げるのも1つの手かと思われる。

小型PCの魅力とオススメの機種について書いた記事があるので、もしよければ参考にして欲しい。

ITipsと同じようなブログを作る方法

ブログに興味がありますか?

もしブログに興味がある場合は↓このページ↓を参考にすれば、ITipsと同じ構成でブログを作ることができます

サーバー、ドメイン、ASPと【ブログに必要なものは全て】このページに書きました。
同じ構成でブログ作るのはいいけど、記事はマネしないでネ (TДT;)

ランキング参加中

にほんブログ村 IT技術ブログへ

他にもブログやSNSで紹介してくれると励みになります。

はてブのコメントで酷評されると泣きます(´;ω;`)

-Python

© 2024 ITips