2017-12-05 5 views
0

str(a dictionary)json.dumps(a dictionary)の出力の違いは何ですか?私がそれらを印刷すると、彼らは同じように見えます。それらの属性(dir)も同じであるようです(下記参照)。しかし、私は違いがなければならないことを知っています。それを私に説明してもらえますか?str(dict)とjson.dumps(dict)の違い

import json 

aDictionary= {"first": 42, "second":21} 
s = str(aDictionary) 
j = json.dumps(aDictionary) 
s == j # returns false 
dir(s) == dir(j) # returns true 
+3

'str(dict)'は有効なJSONを生成しません。 –

+0

ご意見ありがとうございます。はい、私はそれを体験しましたが、そうでなければ非常に似ている2つの違いをよりよく理解したいと思います。 – hartmut

+0

変数名として 'dict'を使用しないでください。結果を印刷すると違いが分かります。 'str':' '{'first':42、 'second':21} ''とjson: '' {最初の":42 "の第2の":21} "からです。キーの文字列の二重引用符に注目してください。 – roganjosh

答えて

6

str(aDictionary)(だけでなく、repr(aDictionary))は辞書のPythonの表現を生成します。この表現は、のデバッグに役立ち、それ以上のものはには役に立ちません。辞書や文字列などの組み込み型に対しては、有効な表現であるPythonの構文が与えられます。 Python構文とJSON構文は同じように見えるかもしれませんが、は同じものではありませんです。

  • Pythonは、文字列リテラルに一重引用符と二重引用符を使用します。 JSONでは二重引用符しか使用できません。
  • Python Unicode文字列は、Unicodeコードポイントをエンコードするために、\<single letter>,\xhh\uhhhhおよび\Uhhhhhhhhエスケープシーケンスを使用します。後者の形式は非BMPコードポイントに使用されます。 JSONは\<single letter>エスケープの範囲と\uhhhhフォームを使用し、非BMPコードポイントのUTF-16サロゲートペアをコード化します(コードポイントごとに2つの\uhhhhシーケンス)。
  • PythonはNoneオブジェクトを使用し、JSONは特別な「存在しない」センチネル値としてnullを使用します。
  • Pythonはブール値としてTrueFalseを使用し、JSONはtruefalseを使用します。
  • Pythonの辞書キーは任意のハッシュ可能な型にすることができます.JSONは文字列のみをサポートします。だから、

str(dictionary)は、ほとんどの時間を有効なJSON出力を生成しません。あなたのすべてのキーと値が少なくとも1つの一重引用符を持つBMP文字列である場合にのみ、有効なJSONとして解析できるドキュメントになる可能性があります。

具体的な例では、str(aDictionary)の一重引用符であるの文書を生成します。それが有効なJSONないようjson.loads()は、このドキュメントを読み込むことができません。

>>> import json 
>>> aDictionary = {"first": 42, "second":21} 
>>> str(aDictionary) 
"{'first': 42, 'second': 21}" 
>>> json.loads(str(aDictionary)) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python3.6/json/__init__.py", line 354, in loads 
    return _default_decoder.decode(s) 
    File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python3.6/json/decoder.py", line 339, in decode 
    obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 
    File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python3.6/json/decoder.py", line 355, in raw_decode 
    obj, end = self.scan_once(s, idx) 
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1) 

シリアライズとしてstr(pythonobject)を使用しないでください。 ast.literal_eval() functionは、文字列表現から妥当な数のPython組み込み型をロードできますが、JSONを同じジョブに使用するよりも速度が遅く、JSONがニーズに合わない場合はさらに洗練されたdata persistence formatです。

+0

偉大で正確な答え。 – ddor254