1. ホーム
  2. python

[解決済み] Pythonのjsonモジュール、int型辞書のキーを文字列に変換する

2022-04-27 22:54:40

質問

Pythonのjsonモジュール(2.6以降に搭載)で、以下を実行すると、int型辞書のキーが文字列に変換されることがわかりました。

>>> import json
>>> releases = {1: "foo-v0.1"}
>>> json.dumps(releases)
'{"1": "foo-v0.1"}'

ダンプやロード時に文字列をパースすることなく、キーをint型として保存する簡単な方法はないでしょうか? jsonモジュールが提供するフックを使えば可能だと思いますが、この場合もやはりパースが必要です。 私が見落としている引数があるのでしょうか? cheers, chaz

サブ質問です。 回答ありがとうございます。jsonは私が恐れていたように動作するように、多分ダンプの出力を解析することによって、キーの種類を伝える簡単な方法はありますか? また、ダンプを行うコードと、サーバーからjsonオブジェクトをダウンロードしてロードするコードは、両方とも私が書いたものであることに留意してください。

解決方法は?

これは、さまざまなマッピングコレクション間の微妙な違いの1つであり、あなたを苦しめる可能性があります。 JSONはキーを文字列として扱いますが、Pythonは型だけが異なる個別のキーをサポートします。

Pythonでは(Luaでもそうですが)、マッピング(それぞれ辞書とテーブル)のキーはオブジェクトのリファレンスです。 Pythonでは、それらはimmutable型でなければなりません。 __hash__ メソッドを使用します。 (Luaのドキュメントによると、ミュータブルなオブジェクトであっても自動的にオブジェクトのIDをハッシュ/キーとして使用し、同等の文字列が同じオブジェクトにマッピングされることを保証するために文字列インターリングに依存しているようです)。

Perl や Javascript、awk、その他多くの言語では、ハッシュや連想配列など、その言語で呼ばれるもののキーは文字列 (Perl では "scalars") です。 Perl では $foo{1}, $foo{1.0}, and $foo{"1"} のマッピングはすべて同じ参照です。 %foo --- キーは 評価済み をスカラーとして使用します。

JSONは、Javascriptのシリアライズ技術として始まりました。(JSONは J アバ S スクリプト O オブジェクト N という表記があります)。 当然ながら、マッピングの意味論と一致するマッピング記法のための意味論を実装しています。

シリアライズの両端がPythonであるなら、picklesを使った方がいいでしょう。 もし本当にJSONからPythonのネイティブオブジェクトに変換する必要があるなら、2つの選択肢があると思います。 最初に、あなたは ( try: ... except: ... ) を使って、辞書の検索に失敗した場合に、任意のキーを数値に変換することができます。 あるいは、もう一方の側(このJSONデータのシリアライザーまたはジェネレーター)にコードを追加して、各キー値に対してJSONシリアライズを実行させ、それらをキーのリストとして提供することも可能です。 (そしてPythonのコードはまずキーのリストを繰り返し、それらをPythonのネイティブオブジェクトにインスタンス化/デシリアライズし、マッピングから値にアクセスするためにそれらを使用します)。