今回は JSON 形式の文字列を Python で整形して表示する方法をご紹介します。
今回は次の 2 つのパターンを取り上げてみます。
- シンタックスハイライトなし
- シンタックスハイライトあり
早速見ていきましょう。
シンタックスハイライトなし
シンタックスハイライトが要らない場合は、標準ライブラリの json
が使えます。
JSON が文字列に格納されている場合
JSON を格納した文字列が Python コードの中で取得できている場合は、いったん loads()
で読み込んだ後に dumps()
で再度ダンプし直すと OK です。その際に dumps()
のオプション引数 indent
を指定することでインデントの大きさを決めることができます。
import json
JSON_SAMPLE = '{"_meta": {"hash": {"sha256": "hash"}, "pipfile-spec": 6, "requires": {"python_version": "3.6"}, "sources": [{"name": "pypi", "url": "https://pypi.python.org/simple", "verify_ssl": true } ] } }'
data = json.loads(JSON_SAMPLE)
print(json.dumps(data, indent=2))
出力結果:
{
"_meta": {
"hash": {
"sha256": "hash"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3.6"
},
"sources": [
{
"name": "pypi",
"url": "https://pypi.python.org/simple",
"verify_ssl": true
}
]
}
}
JSON がファイルに格納されている場合
JSON 文字列がファイルに格納されている場合は、 load()
と open()
を使用します。
上のコードの場合は loads()
の部分を load()
に変えて、引数を文字列からファイルオブジェクトに変更すれば OK です。
import json
JSON_FILE = 'data.json'
with open(JSON_FILE) as f:
data = json.load(f)
print(json.dumps(data, indent=2))
Python プログラムの中ではなくターミナル上で処理できればそれで十分な場合は、 json.tool
モジュールを使う方法がお手軽でおすすめです。 json.tool
は次の形で利用することができます。
$ python -m json.tool < data.json
{
"_meta": {
"hash": {
"sha256": "hash"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3.6"
},
"sources": [
{
"name": "pypi",
"url": "https://pypi.python.org/simple",
"verify_ssl": true
}
]
}
}
python -m json.tool
に JSON 文字列を渡す方法には、上の「標準入力で渡す方法」の他に「ファイル名を引数として渡す方法」もあります。
$ python -m json.tool data.json
出力結果はどちらも同じです。
ちなみに、 python -m json.tool
のヘルプは次のとおりになっています。
python -m json.tool -h
usage: python -m json.tool [-h] [--sort-keys] [infile] [outfile]
A simple command line interface for json module to validate and pretty-print JSON objects.
positional arguments:
infile a JSON file to be validated or pretty-printed
outfile write the output of infile to outfile
optional arguments:
-h, --help show this help message and exit
--sort-keys sort the output of dictionaries alphabetically by key
私は使ったことはありませんが、 dict
型のキーをアルファベット順(辞書順)に並べられる --sort-keys
というオプションがあるようです。
続いて シンタックスハイライトありの方法を見ていきましょう。
シンタックスハイライトあり
シンタックスハイライトを施して JSON を表示する機能は(私が知るかぎり) Python の標準ライブラリには無いので、何らかの非標準のライブラリを使用するか自分で書くかのどちらかになります。おすすめなのは pygments
というライブラリを使用する方法です。
シンタックスハイライトなしの場合と同様に JSON が Python コード内で文字列として取得できている場合から見ていきましょう。
JSON が文字列に格納されている場合
pygments.highlight()
関数にコードの文字列を渡すと、シンタックスハイライトを施した形で文字列を返してくれるので、それを利用します。
import json
from pygments import highlight
from pygments.lexers import JsonLexer
from pygments.formatters import TerminalFormatter
JSON_SAMPLE = '{"_meta": {"hash": {"sha256": "hash"}, "pipfile-spec": 6, "requires": {"python_version": "3.6"}, "sources": [{"name": "pypi", "url": "https://pypi.python.org/simple", "verify_ssl": true } ] } }'
data = json.loads(JSON_SAMPLE)
formatted_data = json.dumps(data, indent=2)
print(highlight(formatted_data, JsonLexer(), TerminalFormatter()))
このコードの出力は次のとおりとなります。ターミナル上ではきれいにハイライトが行われて表示されます。
{
"_meta": {
"hash": {
"sha256": "hash"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3.6"
},
"sources": [
{
"name": "pypi",
"url": "https://pypi.python.org/simple",
"verify_ssl": true
}
]
}
}
出力をブラウザで利用したい場合等は、 TerminalFormatter
の代わりに HtmlFormatter
を利用することが利用できます。
import json
from pygments import highlight
from pygments.lexers import JsonLexer
from pygments.formatters import TerminalFormatter
JSON_SAMPLE = '{"_meta": {"hash": {"sha256": "hash"}, "pipfile-spec": 6, "requires": {"python_version": "3.6"}, "sources": [{"name": "pypi", "url": "https://pypi.python.org/simple", "verify_ssl": true } ] } }'
data = json.loads(JSON_SAMPLE)
formatted_data = json.dumps(data, indent=2)
print(highlight(formatted_data, JsonLexer(), TerminalFormatter()))
JSON がファイルに格納されている場合
JSON がファイルに格納されている場合は、もしターミナル上で扱えればよいだけであれば、 pygments
が提供するコマンドラインツール pygmentize
を使う方法がシンプルでおすすめです。
改行やインデントを保ったままハイライトだけができればよいのであれば、 pygmentize
コマンドをそのまま使用すれば OK です。
$ pygmentize data.json
{"_meta": {"hash": {"sha256": "hash"}, "pipfile-spec": 6, "requires": {"python_version": "3.6"}, "sources": [{"name": "pypi", "url": "https://pypi.python.org/simple", "verify_ssl": true } ] } }
ファイルの拡張子が json
の場合は自動で JSON と認識してくれるようです。拡張子が json
以外の場合は -l
(--lexer
) オプションでフォーマットが JSON であることを伝えれば OK です。
$ pygmentize -l json Pipfile.lock
改行やインデントをよきように調整してなおかつハイライトしてほしい場合は、標準ライブラリ json
と組み合わせて使うとよいかと思います。 pygmentize
コマンドも、対象のファイルが指定されなければ代わりに標準入力の文字列を処理してくれます。
$ python -m json.tool json_data.json | pygmentize -l json
{
"_meta": {
"hash": {
"sha256": "hash"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3.6"
},
"sources": [
{
"name": "pypi",
"url": "https://pypi.python.org/simple",
"verify_ssl": true
}
]
}
}
ヘルプドキュメントの分量が多いのでここには掲載しませんが、 pygmentize
には豊富なオプションがあるので、使ってみたい方は一度確認してから使ってみることをおすすめします。
$ pygmentize --help