python处理json_Python处理JSON
Python處理JSON
(如果閱讀效果不佳,可戳這里)
概念
序列化(Serialization):將對象的狀態信息轉換為可以存儲或可以通過網絡傳輸的過程,傳輸的格式可以是JSON、XML等。反序列化就是從存儲區域(JSON,XML)讀取反序列化對象的狀態,重新創建該對象。
JSON(JavaScript Object Notation):一種輕量級數據交換格式,相對于XML而言更簡單,也易于閱讀和編寫,機器也方便解析和生成,Json是JavaScript中的一個子集。
Python2.6開始加入了JSON模塊,無需另外下載,Python的Json模塊序列化與反序列化的過程分別是 encoding和 decoding
encoding:把一個Python對象編碼轉換成Json字符串
decoding:把Json格式字符串解碼轉換成Python對象
對于簡單數據類型(string、unicode、int、float、list、tuple、dict),可以直接處理。
json.dumps方法對簡單數據類型encoding:
import json
data = [{'a':"A",'b':(2,4),'c':3.0}] #list對象
print "DATA:",repr(data)
data_string = json.dumps(data)
print "JSON:",data_string
輸出:
DATA: [{'a':'A','c':3.0,'b':(2,4)}] #python的dict類型的數據是沒有順序存儲的
JSON: [{"a":"A","c":3.0,"b":[2,4]}]
JSON的輸出結果與DATA很相似,除了一些微妙的變化,如python的元組類型變成了Json的數組,Python到Json的編碼轉換規則是:
json.loads方法處理簡單數據類型的decoding(解碼)轉換
import json
data = [{'a':"A",'b':(2,4),'c':3.0}] #list對象
data_string = json.dumps(data)
print "ENCODED:",data_string
decoded = json.loads(data_string)
print "DECODED:",decoded
print "ORIGINAL:",type(data[0]['b'])
print "DECODED:",type(decoded[0]['b'])
輸出:
ENCODED: [{"a": "A", "c": 3.0, "b": [2, 4]}]
DECODED: [{u'a': u'A', u'c': 3.0, u'b': [2, 4]}]
ORIGINAL:
DECODED:
解碼過程中,json的數組最終轉換成了python的list,而不是最初的tuple類型,Json到Python的解碼規則是:
json的人文關懷
編碼后的json格式字符串緊湊的輸出,而且也沒有順序,因此dumps方法提供了一些可選的參數,讓輸出的格式提高可讀性,如sort_keys是告訴編碼器按照字典排序(a到z)輸出。
import json
data = [ { 'a':'A', 'b':(2, 4), 'c':3.0 } ]
print 'DATA:', repr(data)
unsorted = json.dumps(data)
print 'JSON:', json.dumps(data)
print 'SORT:', json.dumps(data, sort_keys=True)
輸出:
DATA: [{'a': 'A', 'c': 3.0, 'b': (2, 4)}]
JSON: [{"a": "A", "c": 3.0, "b": [2, 4]}]
SORT: [{"a": "A", "b": [2, 4], "c": 3.0}
indent參數根據數據格式縮進顯示,讀起來更加清晰:
import json
data = [ { 'a':'A', 'b':(2, 4), 'c':3.0 } ]
print 'DATA:', repr(data)
print 'NORMAL:', json.dumps(data, sort_keys=True)
print 'INDENT:', json.dumps(data, sort_keys=True, indent=2)
輸出:
DATA: [{'a': 'A', 'c': 3.0, 'b': (2, 4)}]
NORMAL: [{"a": "A", "b": [2, 4], "c": 3.0}]
INDENT: [
{
"a": "A",
"b": [
2,
4
],
"c": 3.0
}
]
separators參數的作用是去掉,,:后面的空格,從上面的輸出結果都能看到", :"后面都有個空格,這都是為了美化輸出結果的作用,但是在我們傳輸數據的過程中,越精簡越好,冗余的東西全部去掉,因此就可以加上separators參數:
import json
data = [ { 'a':'A', 'b':(2, 4), 'c':3.0 } ]
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=2))
print 'dumps(data, separators):', len(json.dumps(data, separators=(',',':')))
輸出:
DATA: [{'a': 'A', 'c': 3.0, 'b': (2, 4)}]
repr(data) : 35
dumps(data) : 35
dumps(data, indent=2) : 76
dumps(data, separators): 29
skipkeys參數,在encoding過程中,dict對象的key只可以是string對象,如果是其他類型,那么在編碼過程中就會拋出ValueError的異常。skipkeys可以跳過那些非string對象當作key的處理.
import json
data= [ { 'a':'A', 'b':(2, 4), 'c':3.0, ('d',):'D tuple' } ]
try:
print json.dumps(data)
except (TypeError, ValueError) as err:
print 'ERROR:', err
print json.dumps(data, skipkeys=True)
輸出:
ERROR: keys must be a string
[{"a": "A", "c": 3.0, "b": [2, 4]}]
讓json支持自定義數據類型
以上例子都是基于python的built-in類型的,對于自定義類型的數據結構,json模塊默認是沒法處理的,會拋出異常:TypeError xx is not JSON serializable,此時你需要自定義一個轉換函數:
import json
class MyObj(object):
def __init__(self, s):
self.s = s
def __repr__(self):
return '' % self.s
obj = .MyObj('helloworld')
try:
print json.dumps(obj)
except TypeError, err:
print 'ERROR:', err
#轉換函數
def convert_to_builtin_type(obj):
print 'default(', repr(obj), ')'
# 把MyObj對象轉換成dict類型的對象
d = { '__class__':obj.__class__.__name__,
'__module__':obj.__module__,
}
d.update(obj.__dict__)
return d
print json.dumps(obj, default=convert_to_builtin_type)
輸出:
ERROR: is not JSON serializable
default( )
{"s": "hellworld", "__module__": "MyObj", "__class__": "__main__"}
#注意:這里的class和module根據你代碼的所在文件位置不同而不同
相反,如果要把json decode 成python對象,同樣也需要自定轉換函數,傳遞給json.loads方法的object_hook參數:
#jsontest.py
import json
class MyObj(object):
def __init__(self,s):
self.s = s
def __repr__(self):
return "" % self.s
def dict_to_object(d):
if '__class__' in d:
class_name = d.pop('__class__')
module_name = d.pop('__module__')
module = __import__(module_name)
print "MODULE:",module
class_ = getattr(module,class_name)
print "CLASS",class_
args = dict((key.encode('ascii'),value) for key,value in d.items())
print 'INSTANCE ARGS:',args
inst = class_(**args)
else:
inst = d
return inst
encoded_object = '[{"s":"helloworld","__module__":"jsontest","__class__":"MyObj"}]'
myobj_instance = json.loads(encoded_object,object_hook=dict_to_object)
print myobj_instance
輸出:
MODULE:
CLASS
INSTANCE ARGS: {'s': u'helloworld'}
[]
MODULE:
CLASS
INSTANCE ARGS: {'s': u'helloworld'}
[]
使用Encoder與Decoder類實現json編碼的轉換
JSONEncoder有一個迭代接口iterencode(data),返回一系列編碼的數據,他的好處是可以方便的把逐個數據寫到文件或網絡流中,而不需要一次性就把數據讀入內存.
import json
encoder = json.JSONEncoder()
data = [ { 'a':'A', 'b':(2, 4), 'c':3.0 } ]
for part in encoder.iterencode(data):
print 'PART:', part
輸出:
PART: [
PART: {
PART: "a"
PART: :
PART: "A"
PART: ,
PART: "c"
PART: :
PART: 3.0
PART: ,
PART: "b"
PART: :
PART: [2
PART: , 4
PART: ]
PART: }
PART: ]
encode方法等價于''.join(encoder.iterencode(),而且預先會做些錯誤檢查(比如非字符串作為dict的key),對于自定義的對象,我們只需從些JSONEncoder的default()方法,其實現方式與上面提及的函數convet_to_builtin_type()是類似的。
import json
import json_myobj
class MyObj(object):
def __init__(self,s):
self.s = s
def __repr__(self):
return "" % self.s
class MyEncoder(json.JSONEncoder):
def default(self, obj):
print 'default(', repr(obj), ')'
# Convert objects to a dictionary of their representation
d = { '__class__':obj.__class__.__name__,
'__module__':obj.__module__,
}
d.update(obj.__dict__)
return d
obj = json_myobj.MyObj('helloworld')
print obj
print MyEncoder().encode(obj)
輸出:
default( )
{"s": "helloworld", "__module__": "Myobj", "__class__": "MyObj"}
從json對Python對象的轉換:
class MyDecoder(json.JSONDecoder):
def __init__(self):
json.JSONDecoder.__init__(self, object_hook=self.dict_to_object)
def dict_to_object(self, d):
if '__class__' in d:
class_name = d.pop('__class__')
module_name = d.pop('__module__')
module = __import__(module_name)
print 'MODULE:', module
class_ = getattr(module, class_name)
print 'CLASS:', class_
args = dict( (key.encode('ascii'), value) for key, value in d.items())
print 'INSTANCE ARGS:', args
inst = class_(**args)
else:
inst = d
return inst
encoded_object = '[{"s": "helloworld", "__module__": "jsontest", "__class__": "MyObj"}]'
myobj_instance = MyDecoder().decode(encoded_object)
print myobj_instance
輸出:
MODULE:
CLASS:
INSTANCE ARGS: {'s': u'helloworld'}
[]
json格式字符串寫入到文件流中
上面的例子都是在內存中操作的,如果對于大數據,把他編碼到一個類文件(file-like)中更合適,load()和dump()方法就可以實現這樣的功能。
import json
import tempfile
data = [ { 'a':'A', 'b':(2, 4), 'c':3.0 } ]
f = tempfile.NamedTemporaryFile(mode='w+')
json.dump(data, f)
f.flush()
print open(f.name, 'r').read()
輸出:
[{"a": "A", "c": 3.0, "b": [2, 4]}]
類似的:
import json
import tempfile
f = tempfile.NamedTemporaryFile(mode='w+')
f.write('[{"a": "A", "c": 3.0, "b": [2, 4]}]')
f.flush()
f.seek(0)
print json.load(f)
輸出:
[{u'a': u'A', u'c': 3.0, u'b': [2, 4]}]
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的python处理json_Python处理JSON的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一个封锁操作被对 wsacancelbl
- 下一篇: python中文显示不出来_Python