何が起きたか?
.iniから読み込んだリストの形をした文字列をlist()
で変換したら期待外れな値が返ってきた。
解決方法
ast.literal_eval()
を使う。
目次
問題の.iniファイル
test.ini
[test]
target_l=[10,20,30]
そのまま出力
>>> import configparser
>>> config = configparser.ConfigParser()
>>> config.read('test.ini')
>>> target_l = config['test']['target_l']
>>> print(target_l)
'[10,20,30]' #文字列
文字列じゃなくてリストにしたい...
間違ったやり方
>>> import configparser
>>> config = configparser.ConfigParser()
>>> config.read('test.ini')
>>> target_l = list(config['test']['target_l'])
>>> print(target_l)
['[', '1', '0', ',', '2', '0', ',', '3', '0', ']'] #中身が一文字ずつ文字列に(汗)
正しいやり方
>>> import configparser
>>> import ast
>>> config = configparser.ConfigParser()
>>> config.read('test.ini')
>>> target_l = ast.literal_eval(config['test']['target_l'])
>>> print(target_l)
[10,20,30]
ちなみに辞書も
test.ini
[test]
target_d={'a':'1', 'b':'2', 'c':'3'}
>>> import configparser
>>> import ast
>>> config = configparser.ConfigParser()
>>> config.read('test.ini')
>>> target_d = ast.literal_eval(config['test']['target_d'])
>>> print(target_d)
{'a':'1', 'b':'2', 'c':'3'}
ast.literal_eval()とeval()
今回の例では組み込み関数のeval()
用いても同様な結果を得ることが可能です。
しかしeval()
の主な用途は文字列をコマンドとして評価して実行することであるため、使用する際は注意が必要です。
eval("os.remove(test.py)")
一方、literal_eval()
の場合は文字通りリテラルな文字列を対象とするため、別途定義された変数などを参照するとエラーを返してくれます。