morikomorou’s blog

自分が学んだことなどの備忘録的なやつ

【python】設定ファイル(yaml)の読み書き方法を解説


yamlという設定ファイルの扱い方や、どういうときに使うかを解説したいと思います。何となくよく聞くし使ってみようとおもって使ってみましたが、少々癖があったのでその点も説明します。

はじめに

設定ファイルってよく聞くけどなんだろうって感じでした。よくアプリケーションを使ったときに勝手に出来上がるconfig.iniみたいなものも設定ファイルと呼ばれるものです。
wikiでは以下のように説明されています。

設定ファイル(せっていふぁいる、英語: configuration file)とは、コンピュータにおいて、動作するプログラムや、オペレーティングシステム (OS) 等の、様々な設定上の条件を記述したファイルである。

設定ファイル - Wikipedia

プログラムのユーザがプログラムをいじらず設定を変えれるようにするために使われたりします。体系化されたテキスト形式のファイルで、iniファイルやjsonファイル等いろいろ書き方に種類がありますが、今回はかっこよさそうなのでyamlファイルを使ってみたいと思います。




設定ファイルの使い道

私が実際に使ってみて役立ったなと思うのは下記のような場面でした。

  • アプリでユーザが選択したパラメータ等を次回起動時に引き継ぎたいとき
  • シミュレーション等のプログラムで、プログラムを編集することなくパラメータをころころ変えたいとき

yamlを使ってみる

それではさっそく使ってみましょう。yamlファイルはiniファイルと比べて人間に対して見やすい、書きやすいという利点があるようです。

pythonでyamlを扱うためにはPyYamlというライブラリを使用します。コマンドラインに以下の呪文を打ち込んでインストールしておきます。

pip install pyyaml

yamlファイルの書き方

yamlはpythonでいう辞書みたいにキーと値の組み合わせを書きます。
以下のように:(半角スペース)の左側にキー、右側に値を記入します。

key1: 'a'
key2: 3
key3: ['リストも', '入れられます']
key4: {'辞書': 'も入れられます'}
# コメントはpythonと同様に# をつけて書きます
key5:
    key5_1: 'ネストはインデントで表現します'
    key5_2: 3489
    key5_3: [{'a': 2}, [12, 3]]

yamlファイルの読み込み

先ほどの例をtest.yamlという形で保存しておいて、python側で読み込んでみましょう。

import yaml
import pprint

with open('test.yaml', 'rb') as f:
    yml = yaml.safe_load(f)

pprint.pprint(yml)

日本語を含むyamlファイルを読み込む場合は、ファイルを開く際に'rb'モードじゃないとエラーになってしまうので注意です。yamlファイルの読み込みはyaml.safe_load()で行います。

結果は以下の通り。yamlファイルを読み込むと辞書形式で読み込めます。値に指定していしたリストや辞書、文字列や数字もちゃんとその型で読み込まれています。

{'key1': 'a',
 'key2': 3,
 'key3': ['リストも', '入れられます'],
 'key4': {'辞書': 'も入れられます'},
 'key5': {'key5_1': 'ネストはインデントで表現します',
          'key5_2': 3489,
          'key5_3': [{'a': 2}, [12, 3]]}}




yamlファイルの書き込み

先ほど読み込んだものを少し変えたり、追加した後にyamlファイルを書き出してみましょう。

import yaml
import pprint

# 読み込み
with open('test.yaml', 'rb') as f:
    yml = yaml.safe_load(f)

# 変更、追記
yml['key1'] = '変更した!'
yml['追加したkey'] = ['このキーを', '追加した']

# 書き出し
with open('test2.yaml', 'wb') as f:
    yaml.dump(yml, f, encoding='utf-8', allow_unicode=True)

こちらも日本語を使う際はファイルをwbモードで開く必要があります。
書き込みはyaml.dump()でできますが、日本語を扱う際はencodingとallow_unicodeオプションを指定する必要があります(文字化けやエラーになります)。

結果は以下です。

key1: 変更した!
key2: 3
key3:
- リストも
- 入れられます
key4:
  辞書: も入れられます
key5:
  key5_1: ネストはインデントで表現します
  key5_2: 3489
  key5_3:
  - a: 2
  - - 12
    - 3
追加したkey:
- このキーを
- 追加した

ちょっと書き方が変わってしまいましたが、ちゃんと書き出せました。もともと書いてたのはインライン記法というもので、pyyamlで書き出されるものは、一行に1アイテムのこの記入方法になるようで(ドキュメント見たけど変えられそうになかった)。なのでこっちで慣れたほうがいいかもしれません。
詳しくは以下が参考になりました。

おわりに

yamlをさわってみました。大体わかってきましたが、日本語を使うときにいろいろめんどくさいのが少し難点ですね。そこらへんはiniファイルのほうが簡単だし、良い気がします。