データアナリティクス事業本部のueharaです。
今回は、Python 3.11で追加されたtomlibを使ってみたいと思います。
tomlibとは
Python 3.11で追加されたTOML(Tom's Obvious Minimal Language)を解析するための標準モジュールです。
このモジュールではTOMLの書き出しはサポートされておらず、あくまでパース用のモジュールになります。
TOMLについて知りたい方は以下をご確認ください。
環境構築
平素使っているPythonの実行環境に影響を与えたくないので、dockerでPython 3.11の実行環境を構築します。
準備するフォルダ構成は以下の通りです。
.
├ compose.yml
└ scripts
├ test.py
└ data.toml
compose.ymlの記載
compose.ymlを、以下のように記載します。
compose.yml
services:
python311:
container_name: python311
image: python:3.11.4-bookworm
working_dir: /root/scripts
volumes:
- ./scripts:/root/scripts
tty: true
compose.yml
ファイルと同じ階層に作成したscripts
フォルダをコンテナ側の/root/scripts
にマウントし、作業用ディレクトリに指定しています。
起動と接続
compose.yml
の準備が完了したら、コンテナの起動と接続を行います。
# コンテナの起動
$ docker compose up -d
# コンテナへの接続(bashの起動)
$ docker compose exec python311 bash
以下のように接続でき、コマンドが実行できれば成功です。
tomlibを使ってみる
TOMLとPythonの対応表は以下の通りです。
TOML | Python |
---|---|
table | dict |
string | str |
integer | int |
float | float (configurable with parse_float) |
boolean | bool |
offset date-time | datetime.datetime (tzinfo attribute set to an instance of datetime.timezone) |
local date-time | datetime.datetime (tzinfo attribute set to None) |
local date | datetime.date |
local time | datetime.time |
array | list |
また、tomlibにはTOML形式のデータを読み込むのにファイルからの読み込みと文字列からの読み込みがあります。
ファイルからの読み込み
tomllib.load
関数でTOMLファイルを読み込むことができます。
テスト用のTOMLファイルはとりあえず網羅的に以下のようにしてみました。(テーブルを正しく認識させるには、テーブルデータを末尾にもっていく必要があります)
data.toml
# string
data01 = "hoge"
# integer
data02 = 10
# float
data03 = 1.23
# boolean
data04 = true
# offset date-time
data05 = 2023-08-02T07:32:00+09:00
# local date-time
data06 = 2023-08-02T07:32:00
# local date
data07 = 2023-08-02
# local time
data08 = 07:32:00
# array
data09 = [1, 2, 3, 4, 5]
# table
[data10]
key1 = "foo"
key2 = 123
test.py
import tomllib
import pprint
with open("data.toml", "rb") as f:
data = tomllib.load(f)
pprint.pprint(data)
pprint.pprint([type(v) for v in data.values()])
実行結果は以下の通りです。
$ python test.py
{'data01': 'hoge',
'data02': 10,
'data03': 1.23,
'data04': True,
'data05': datetime.datetime(2023, 8, 2, 7, 32, tzinfo=datetime.timezone(datetime.timedelta(seconds=32400))),
'data06': datetime.datetime(2023, 8, 2, 7, 32),
'data07': datetime.date(2023, 8, 2),
'data08': datetime.time(7, 32),
'data09': [1, 2, 3, 4, 5],
'data10': {'key1': 'foo', 'key2': 123}}
[<class 'str'>,
<class 'int'>,
<class 'float'>,
<class 'bool'>,
<class 'datetime.datetime'>,
<class 'datetime.datetime'>,
<class 'datetime.date'>,
<class 'datetime.time'>,
<class 'list'>,
<class 'dict'>]
本章の冒頭で示したテーブル通りのマッピングになっていることが分かります。
※例:TOMLのオフセット付日時 2023-08-02T07:32:00+09:00
が Pythonのtzinfoが設定されたdatetime datetime.datetime(2023, 8, 2, 7, 32, tzinfo=datetime.timezone(datetime.timedelta(seconds=32400)))
になっている。
文字列からの読み込み
tomllib.loads
関数で文字列のTOML形式を読み込むことができます。
test.py
import tomllib
toml_str = """
python-version = "3.11.0"
python-implementation = "CPython"
"""
data = tomllib.loads(toml_str)
print(data)
実行結果は以下の通りです。
$ python test.py
{'python-implementation': 'CPython', 'python-version': '3.11.0'}
float型のパースについて
また、floatについては、tomllib.load
, tomllib.loads
関数共にparse_float
引数に別のデータ型を渡すことができます。(デフォルトはfloat
)
test.py
import decimal
import tomllib
toml_str = """
data01 = 1.23
data02 = 0.99999999999999999
"""
data = tomllib.loads(toml_str, parse_float=decimal.Decimal)
print(data)
print([type(v) for v in data.values()])
decimal.Decimal
を渡した場合、実行結果は以下の通りです。
$ python test.py
{'data01': Decimal('1.23'), 'data02': Decimal('0.99999999999999999')}
[<class 'decimal.Decimal'>, <class 'decimal.Decimal'>]
最後に
今回は、Python 3.11で追加されたtomlibを使ってみました。
参考になりましたら幸いです。