この記事では、例を通じて json 上の Python の関連操作を分析します。参考のために皆さんと共有してください。詳細は次のとおりです:
json とは:
JSON (JavaScript Object Notation) は軽量のデータ交換形式です。人間にとって読み書きしやすい。機械による解析と生成も簡単です。これは、JavaScript プログラミング言語、標準 ECMA-262 第 3 版 (1999 年 12 月) のサブセットに基づいています。 JSON は完全に言語に依存しないテキスト形式を使用しますが、C 言語ファミリー (C、C++、C#、Java、JavaScript、Perl、Python など) に似た規則も使用します。これらの特性により、JSON は理想的なデータ交換言語になります。
JSON は 2 つの構造から構築されます:
名前と値のペアのコレクション。さまざまな言語では、オブジェクト、レコード、構造体、辞書、ハッシュ テーブル、キー付きリスト、または連想配列として理解されます。
値の順序付きリスト。ほとんどの言語では、これは配列として理解されます。
これらは一般的なデータ構造です。実際、最新のコンピューター言語のほとんどは、何らかの形でそれらをサポートしています。これにより、同様にこれらの構造に基づくプログラミング言語間でデータ形式を交換できるようになります。
json の公式説明については、http://json.org/
json を操作するための Python の標準 API ライブラリ リファレンス: http://docs.python.org/library/json.html
エンコーディングとエンコーディング単純なデータ型のデコード:
単純な json.dumps メソッドを使用して、次のような単純なデータ型をエンコードします:
import json obj = [[1,2,3],123,123.123,'abc',{'key1':(1,2,3),'key2':(4,5,6)}] encodedjson = json.dumps(obj) print repr(obj) print encodedjson
出力:
[[1, 2, 3], 123, 123.123, 'abc', {'key2': (4, 5, 6), 'key1': (1, 2, 3)}] [[1, 2, 3], 123, 123.123, "abc", {"key2": [4, 5, 6], "key1": [1, 2, 3]}]
出力結果からわかるように、単純な型がエンコードされ、その後にその単純な型がエンコードされます。元の repr() の出力結果は非常に似ていますが、いくつかのデータ型が変更されています。たとえば、上の例のタプルはリストに変換されます。 json のエンコード処理中に、Python の元の型から json 型への変換処理が行われます。具体的な変換比較は次のとおりです。
json.dumps() メソッドは、次に encodedjson の str オブジェクトを返します。元のデータをデコードして取得するには、json.loads() 関数を使用する必要があります:
decodejson = json.loads(encodedjson) print type(decodejson) print decodejson[4]['key1'] print decodejson
出力:
<type 'list'> [1, 2, 3] [[1, 2, 3], 123, 123.123, u'abc', {u'key2': [4, 5, 6], u'key1': [1, 2, 3]}]
loads メソッドは元のオブジェクトを返しますが、一部のデータ型変換は依然として行われます。起こる 。たとえば、上記の例では、「abc」が Unicode 型に変換されます。 json から Python への型変換の比較は次のとおりです:
json.dumps メソッドには、選択できる多くの便利なパラメーターが用意されています。より一般的に使用されるのは、sort_keys (辞書オブジェクトの並べ替え、デフォルトの辞書が保存されていることがわかっています)順不同)、区切り文字、インデント、その他のパラメータ。
並べ替え機能により、保存されたデータが観察しやすくなり、次のような json 出力オブジェクトの比較も可能になります。 data2 data これらは同じである必要がありますが、辞書ストレージの順序付けされていない性質のため、この 2 つを比較することはできません。したがって、データの不整合を避けるために、これら 2 つをソート結果を通じて保存することができます。ただし、ソート後に保存する前に、システムはより多くのことを行う必要があり、ある程度のパフォーマンスの消費が確実に発生するため、適切なソートが非常に重要です。
indent パラメーターはインデントを意味し、データ ストレージの形式をよりエレガントにすることができます。
data1 = {'b':789,'c':456,'a':123} data2 = {'a':123,'b':789,'c':456} d1 = json.dumps(data1,sort_keys=True) d2 = json.dumps(data2) d3 = json.dumps(data2,sort_keys=True) print d1 print d2 print d3 print d1==d2 print d1==d3
出力:
{"a": 123, "b": 789, "c": 456} {"a": 123, "c": 456, "b": 789} {"a": 123, "b": 789, "c": 456} False True
出力データはフォーマットされると読みやすくなりますが、冗長な空白セルが追加されることで埋められます。 JSON は主にデータ通信形式として存在し、ネットワーク通信ではデータのサイズが非常に懸念されるため、無駄なスペースが多くの通信帯域を占有するため、必要に応じてデータを圧縮する必要があります。セパレータ パラメータは、この役割を果たすことができます。渡されるパラメータは、分割オブジェクトの文字列を含むタプルです。
data1 = {'b':789,'c':456,'a':123} d1 = json.dumps(data1,sort_keys=True,indent=4) print d1
出力:
{ "a": 123, "b": 789, "c": 456 }
冗長な空白文字を削除することで、データ圧縮の目的が達成され、その効果は非常に明白です。
もう 1 つの便利なダンプ パラメーターは Skipkeys で、デフォルトは False です。 dumps メソッドが dict オブジェクトを格納する場合、キーは str 型である必要があります。他の型が出現した場合、このパラメーターをオンにして True に設定すると、より安全になります。
print 'DATA:', repr(data) print 'repr(data) :', len(repr(data)) print 'dumps(data) :', len(json.dumps(data)) print 'dumps(data, indent=2) :', len(json.dumps(data, indent=4)) print 'dumps(data, separators):', len(json.dumps(data, separators=(',',':')))
出力:
DATA: {'a': 123, 'c': 456, 'b': 789} repr(data) : 30 dumps(data) : 30 dumps(data, indent=2) : 46 dumps(data, separators): 25
独自のデータ型を処理します
json モジュールは、通常の Python 組み込み型だけでなく、カスタム データ型も処理でき、多くの場合、カスタム オブジェクトも処理できますは非常に一般的に使用されます。
まず、クラス person を定義します。
りー
如果直接通过json.dumps方法对Person的实例进行处理的话,会报错,因为json无法支持这样的自动转化。通过上面所提到的json和python的类型转化对照表,可以发现,object类型是和dict相关联的,所以我们需要把我们自定义的类型转化为dict,然后再进行处理。这里,有两种方法可以使用。
方法一:自己写转化函数
''' Created on 2011-12-14 @author: Peter ''' import Person import json p = Person.Person('Peter',22) def object2dict(obj): #convert object to a dict d = {} d['__class__'] = obj.__class__.__name__ d['__module__'] = obj.__module__ d.update(obj.__dict__) return d def dict2object(d): #convert dict to object if'__class__' in d: class_name = d.pop('__class__') module_name = d.pop('__module__') module = __import__(module_name) class_ = getattr(module,class_name) args = dict((key.encode('ascii'), value) for key, value in d.items()) #get args inst = class_(**args) #create new instance else: inst = d return inst d = object2dict(p) print d #{'age': 22, '__module__': 'Person', '__class__': 'Person', 'name': 'Peter'} o = dict2object(d) print type(o),o #<class 'Person.Person'> Person Object name : Peter , age : 22 dump = json.dumps(p,default=object2dict) print dump #{"age": 22, "__module__": "Person", "__class__": "Person", "name": "Peter"} load = json.loads(dump,object_hook = dict2object) print load #Person Object name : Peter , age : 22
上面代码已经写的很清楚了,实质就是自定义object类型和dict类型进行转化。object2dict函数将对象模块名、类名以及__dict__存储在dict对象里,并返回。dict2object函数则是反解出模块名、类名、参数,创建新的对象并返回。在json.dumps 方法中增加default参数,该参数表示在转化过程中调用指定的函数,同样在decode过程中json.loads方法增加object_hook,指定转化函数。
方法二:继承JSONEncoder和JSONDecoder类,覆写相关方法
JSONEncoder类负责编码,主要是通过其default函数进行转化,我们可以override该方法。同理对于JSONDecoder。
''' Created on 2011-12-14 @author: Peter ''' import Person import json p = Person.Person('Peter',22) class MyEncoder(json.JSONEncoder): def default(self,obj): #convert object to a dict d = {} d['__class__'] = obj.__class__.__name__ d['__module__'] = obj.__module__ d.update(obj.__dict__) return d class MyDecoder(json.JSONDecoder): def __init__(self): json.JSONDecoder.__init__(self,object_hook=self.dict2object) def dict2object(self,d): #convert dict to object if'__class__' in d: class_name = d.pop('__class__') module_name = d.pop('__module__') module = __import__(module_name) class_ = getattr(module,class_name) args = dict((key.encode('ascii'), value) for key, value in d.items()) #get args inst = class_(**args) #create new instance else: inst = d return inst d = MyEncoder().encode(p) o = MyDecoder().decode(d) print d print type(o), o
对于JSONDecoder类方法,稍微有点不同,但是改写起来也不是很麻烦。看代码应该就比较清楚了。
希望本文所述对大家Python程序设计有所帮助。
更多json上でのPython関連の操作例を詳しく解説相关文章请关注PHP中文网!