PythonでJSON with Commentsを使う

# 目次

1. [Pythonファイルへのデータ直書きに待った](#pythonファイルへのデータ直書きに待った)
2. [JSON with Comments とは](#json-with-comments-とは)
3. [JSONCファイルをPythonで読み込む](#jsoncファイルをpythonで読み込む)
4. [参考文献](#参考文献)

# Pythonファイルへのデータ直書きに待った

お急ぎの方は読み飛ばしてください。

例えば、都道府県庁所在地を辞書型で持つ、という状況を考えてみましょう。
Pythonファイルにデータを直書きしてしまうと、以下のような感じになってしまうでしょう。

```hoge.py
dict_prefectural_capital = {'北海道': '札幌', '青森県': '青森',
                            ... (略) ... ,
                            '沖縄県': '那覇'}
```

このデータをここからさらにいじりたい時（具体例悪くてすみません・・・）とかは、この後に処理を書かなければならず、ファイルが冗長になってしまいます。
さらに、兵庫県の県庁所在地が神戸から姫路に変わってしまった！なんてことが地球が滅びる前に起こらないとは言い切れません。そんな時、わざわざ処理も書かれているファイルを、ほんの少しではありますがいじってしまうことになって、怖い気持ちになります。
そんな時に登場するのが、JSONファイルになります。これを使うと、データのファイル（JSONファイル）とデータを処理するファイル（Pythonファイル）に分けることができて、嬉しい気持ちになります。
JSONの記法については、調べればすぐ出てきますし、かなり簡単な記法となっていますので省略しますが、以下のような感じで書けると思います。

```hoge.json
{
    "北海道": "札幌", "青森県": "青森", ... (略) ... , "沖縄県": "那覇"
}
```

これを Pythonファイルから読み込むためには、簡単に書けば次のようになります。

```hoge.py
import json

with open('hoge.json') as f:
    dict_prefectural_capital = json.load(f)
```

# JSON with Comments とは

本題です。JSONファイルを使う際に、困ったことがあります。
それは、コメントアウトが何一つ書けない、ということです。
そして、その問題点を解決するのが、JSON with Comments形式（以下 JSONC形式）というわけです。
コメントアウトの形式は、C言語と同じで、以下のような感じになります。（JSON形式でコード挿入してるので、エラーっぽい表示が出てしまっていますが、大丈夫です。）

```json
// 1行コメント
/*
複数行コメント
*/
/* もちろん1行でも */
```

VSCode でも対応しているファイル形式で、ファイルの拡張子を .jsonc としてあげれば、勝手に認識してくれます。（以下の写真はその時の VSCode の右下の表示）
![スクリーンショット (44).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1583044/c61c8c0e-3d3f-3114-1c5c-b07da51a19a4.png)

この形式を使ってあげれば、以下のように、適宜コメントアウトを挟みつつ、どこにどのデータが記されているのかが分かりやすいファイルを作ってあげることができます。

```hoge.jsonc
{
    /* 北海道 */
    "北海道": "札幌",
    
    /* 東北 */
    "青森県": "青森", ... (略) ... ,
    
    /* 沖縄 */
    "沖縄県": "那覇"  // 沖縄市じゃないよ
}
```

# JSONCファイルをPythonで読み込む

本題 Part2 です。
便利そうに見える JSONCファイルですが、Python で読み込むときにはどうすればよいでしょうか？
コメントアウトの部分を正規表現で取り出すことができれば、あとは JSONファイルと全く同じ処理ができそうですね。
ということで、[参考文献2](https://qiita.com/koppe/items/f27be003726b03304b24)で紹介されているコード（を若干変えたもの）を以下に載せます。関数にしておくとやっぱり便利です。

```hoge.py
import re
import json

def load_jsonc(filepath: str, encoding: str = 'utf-8'):
    with open(filepath, 'r', encoding=encoding) as f:                # ファイルを開く (encoding 注意)
        text = f.read()                                              # ファイルの中身を文字列として取得
    text_without_comment = re.sub(r'/\*[\s\S]*?\*/|//.*', '', text)  # 正規表現を使ってコメントを削除
    json_obj = json.loads(text_without_comment)                      # 文字列をjson形式として処理
    return json_obj

dict_prefectural_capital = load_jsonc('hoge.jsonc', encoding='cp932')
```

余談ですが、VSCode で JSONCファイルを作成しているのであれば、先ほど掲載した VSCode のスクリーンショットのところで、UTF-8 とあるところをクリックすると、以下の写真のように VSCode の上部に Reopen with Encoding と Save with Encoding というボタンが出てきて、ファイルのエンコーディングまわりの処理が楽にできます。便利ですね。
![スクリーンショット (45).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1583044/05a10c4f-df67-f8e1-6b5e-c8ae1305a968.png)

いちいちエンコーディングを選ぶのが面倒だって方は、settings.jsonとかに

```settings.json
{
    "[.jsonc]": {
        "files.encoding": "shiftjis"  // Shift-JIS に指定しとく
    }
}
```

という感じで書いて、使いたいものを選んでおけばよいと思います。
作業フォルダごとに .vscode フォルダを用意して、その中に settings.json を用意しておけば、作業フォルダごとに設定をカスタマイズできますね。

さらに余談ですが、VSCode上で settings.json は、JSONC形式として読み込んでくれるみたいなので、コメントもつけ放題です。

# 参考文献

1. [PythonでJSONファイル・文字列の読み込み・書き込み](https://note.nkmk.me/python-json-load-dump/)
2. [Pythonでコメント付きのJSONファイル(JSONC)を読み込む](https://qiita.com/koppe/items/f27be003726b03304b24)
3. [C/C++のコメントにマッチする正規表現](https://qiita.com/itsmypleasure/items/a79c210bae23a29d4ff1)
4. [JSON にもコメントを書きたい](https://qiita.com/yokra9/items/1ac03876415d7fd47a65)