Python json.dumpでわかりやすく出力を表示する

Python学習【365日チャレンジ!】296日目のマスターU(@Udemy11)です。

先日タチウオを釣りに行った際に、壁に立て掛けていたロッドを倒してしまい、リールのスプールエッジを傷つけてしまいました。

スプールエッジに傷がつくと、キャストの際にラインに傷がついてキャスト切れを起こしてしまうので、修復する方法がないかとネットを探しているときれいに直す方法が紹介されていました。

あんまり一般の家庭には揃っていない道具を使っているのですが、どういうわけかすべて揃っていたので、試しにやってみると、スプールエッジの傷がなくなってピッカピカに仕上げることができました。

これで、ラインが傷つく心配もなくなって釣りに集中できそうです。

それでは今日も、Python学習を始めましょう。

昨日の復習

昨日は、出力フォーマットをカスタマイズできるpprintを学習しました。

printはただ出力するだけでしたが、pprintPrettyPrinterを使って出力結果を見やすく表示することができました。

引数のindentwidthcompactdepthなどを使って好みのフォーマットで見やすく出力できました。

詳細については昨日の記事をごらんください。

今日は、よりわかりやすい出力ができるjson.dumpsを学習します。

json.dumps

pprintと同じように見やすい出力にしてくれるのがjson.dumpsです。

import json

l = ['apple', 'banana', 'mango', 'orange', 'peach']
l.insert(0, l[:])

d = {'a': 'A', 'b': 'B', 'c': {'x': {'y': 'Y'}}}

print(json.dumps(l, indent=4))
print(json.dumps(d, indent=4))

3行目から6行目でリストと辞書型の値を定義して、8行目と9行目でリストと辞書型の値をインデントを4つ入れる同じフォーマットで出力しています。

出力結果

[
    [
        "apple",
        "banana",
        "mango",
        "orange",
        "peach"
    ],
    "apple",
    "banana",
    "mango",
    "orange",
    "peach"
]
{
    "a": "A",
    "b": "B",
    "c": {
        "x": {
            "y": "Y"
        }
    }
}

リストも辞書型も階層ごとに改行されて見やすく出力されています。

json.dumpsは、widthdepthを使わなくても見やすいフォーマットにしてくれるのですが、タプルはリストに変換されて出力されるので、PrettyPrinterを使う必要があります。

PyPIから情報を取得

Pythonの公式ドキュメントのpprintの使用例で紹介されているPyPIからデータを取得して、json.dumpsで出力してみます。

import json

from urllib.request import urlopen

with urlopen('https://pypi.org/pypi/sampleproject/json') as resp:
    project_info = json.load(resp)['info']

print(json.dumps(project_info, indent=4))

6行目までは、こちらの公式ドキュメントの使用例をそのままコピーペーストして、8行目でjson.dumpsを使ってprint出力しています。

出力結果

{
    "author": "A. Random Developer",
    "author_email": "author@example.com",
    "bugtrack_url": null,
    "classifiers": [
        "Development Status :: 3 - Alpha",
        "Intended Audience :: Developers",
        "License :: OSI Approved :: MIT License",
        "Programming Language :: Python :: 3",
        "Programming Language :: Python :: 3.5",
        "Programming Language :: Python :: 3.6",
        "Programming Language :: Python :: 3.7",
        "Programming Language :: Python :: 3.8",
        "Programming Language :: Python :: 3 :: Only",
        "Topic :: Software Development :: Build Tools"
    ],
    "description": "# A sample Python project\n\n![Python Logo](https://www.python.org/static/community_logos/python-logo.png \"Sample inline image\")\n\nA sample project that exists as an aid to the [Python Packaging User\nGuide][packaging guide]'s [Tutorial on Packaging and Distributing\nProjects][distribution tutorial].\n\nThis project does not aim to cover best practices for Python project\ndevelopment as a whole. For example, it does not provide guidance or tool\nrecommendations for version control, documentation, or testing.\n\n[The source for this project is available here][src].\n\nMost of the configuration for a Python project is done in the `setup.py` file,\nan example of which is included in this project. You should edit this file\naccordingly to adapt this sample project to your needs.\n\n----\n\nThis is the README file for the project.\n\nThe file should use UTF-8 encoding and can be written using\n[reStructuredText][rst] or [markdown][md use] with the appropriate [key set][md\nuse]. It will be used to generate the project webpage on PyPI and will be\ndisplayed as the project homepage on common code-hosting services, and should be\nwritten for that purpose.\n\nTypical contents for this file would include an overview of the project, basic\nusage examples, etc. Generally, including the project changelog in here is not a\ngood idea, although a simple \u201cWhat's New\u201d section for the most recent version\nmay be appropriate.\n\n[packaging guide]: https://packaging.python.org\n[distribution tutorial]: https://packaging.python.org/tutorials/packaging-projects/\n[src]: https://github.com/pypa/sampleproject\n[rst]: http://docutils.sourceforge.net/rst.html\n[md]: https://tools.ietf.org/html/rfc7764#section-3.5 \"CommonMark variant\"\n[md use]: https://packaging.python.org/specifications/core-metadata/#description-content-type-optional\n\n\n",
    "description_content_type": "text/markdown",
    "docs_url": null,
    "download_url": "",
    "downloads": {
        "last_day": -1,
        "last_month": -1,
        "last_week": -1
    },
    "home_page": "https://github.com/pypa/sampleproject",
    "keywords": "sample setuptools development",
    "license": "",
    "maintainer": "",
    "maintainer_email": "",
    "name": "sampleproject",
    "package_url": "https://pypi.org/project/sampleproject/",
    "platform": "",
    "project_url": "https://pypi.org/project/sampleproject/",
    "project_urls": {
        "Bug Reports": "https://github.com/pypa/sampleproject/issues",
        "Funding": "https://donate.pypi.org",
        "Homepage": "https://github.com/pypa/sampleproject",
        "Say Thanks!": "http://saythanks.io/to/example",
        "Source": "https://github.com/pypa/sampleproject/"
    },
    "release_url": "https://pypi.org/project/sampleproject/2.0.0/",
    "requires_dist": [
        "peppercorn",
        "check-manifest ; extra == 'dev'",
        "coverage ; extra == 'test'"
    ],
    "requires_python": ">=3.5, <4",
    "summary": "A sample Python project",
    "version": "2.0.0",
    "yanked": false,
    "yanked_reason": null
}

ちなみに読み込んだ値は【https://pypi.org/pypi/sampleproject/json】にアクセスしてみるとわかりますが、とんでもなく長い1行のデータです。

そのデータをjson.dumpsで見やすいように改行とインデントを入れて出力しています。

まとめ

コンピューターが値を扱う場合は、最後に紹介したページの長い一行のデータでも、規則に従って保存されていれば問題なく認識してくれます。

しかし、人が見てわかりやすくするには、pprintjson.dumpsを使って表示する必要があります。

リアルの世界でも整理整頓された部屋はきれいで、どこに何があるかひと目で分かるように、Pythonもみてわかりやすいコードが推奨されているので、わかりやすいコード、わかりやすい出力を意識するようにしましょう。

それでは、明日もGood Python!