JSON簡介
JSON(JavaScript Object Notation)是一種輕量級的數據交換格式。易於人閱讀和編寫。同時也易於機器解析和生成。它基於JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一個子集。JSON採用完全獨立於語言的文本格式,但是也使用了類似於C語言家族的習慣(包括C, C++, C#, Java, JavaScript, Perl, Python等)。這些特性使JSON成為理想的數據交換語言。
JSON官方網站
http:
JSON是一種基於文本,獨立於語言的輕量級數據交換格式。JSON的基本語法如下:
1、JSON名稱/值對。JSON 數據的書寫格式是:名稱/值對。名稱/值對包括欄位名稱(在雙引號中),然後著是一個冒號(:),最後是值。比如{ "name" : "Python" },類似於Python中的字典。
2、JSON值。JSON值可以是數字(整數或浮點數),字符串(在雙引號中),邏輯值(True 或False),數組(在中括號中),對象(在大括號中)和null。例如{ "age": 21,"graduated ":true }。JSON值的基本格式如下圖所示。
圖 JSON值的基本格式
3、JSON對象。JSON 對象在花括號({})中書寫,對象可以包含多個名稱/值對,多個JSON名稱/值以」,」進行分隔。例如{ "name":"Pyton" , "age": 25}。JSON對象的基本格式如下圖所示。
圖 JSON對象
4、JSON 數組。JSON 數組在方括號中書寫,數組可包含多個JSON對象。例如:
{
"sites": [
{ "name": "jd", "url": "www.jd.com" },
{ "name": "taobao", "url": "www.taobao.com" }
]
}
在本例中對象」sites」是包含2個對象的數組。JSON數組的的基本格式如下圖所示。
Python操作JSON
Pythone3標準庫有JSON模塊,主要執行序列化和反序列化功能。
1、json模塊的主要函數
在Python3的json模塊中json.dumps()函數將Python對象編碼成JSON字符串。使用的語法如下:
import json
dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)
主要參數說明:
sort_keys:表示序列化JSON對象時是否對字典的key進行排序,字典默認是無序的。
indent:表示縮進,可以是數據格式可讀性更強,格式化輸出JSON字符串,如果ident是一個非負的整數,那麼JSONarray元素和object成員將會被以相應的縮進級別進行列印輸出。
separators:當使用ident參數時json模塊序列化Python對象後得到的JSON字符串中的」,」號和」:」號分隔符後默認會附加一個空白字符,可以通過separators參數重新指定分隔符,去除無用的空白字符。指定的分隔符一般是一個元祖類型的數據,比如(',',':')。
使用json模塊的json.load()函數,將JSON格式的字符串轉換成Python對象,使用的語法格式如下:
import json
json.load(fp, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
2、JSON字符串與Python 原始類型之間數據類型對應關係
Python 原始類型向JSON類型的轉化對照表,如表所示:
表 Python原始類型向JSON類型的轉化對照表
JSON類型向Python 原始類型的轉化對照表,如表所示:
表 JSON類型向Python原始類型的轉化對照表
3、序列化操作實例
import json
data ={'name':"wangwu" , 'lang': ('python' ,'java'), 'age':20 }
data_json = json.dumps( data )
print( data)
# 輸出結果為[{'name': 'wangwu', 'lang': ('python', 'java'), 'age': 20}]
print( data_json )
# 輸出結果為 [{"name": "wangwu", "lang": ["python", "java"], "age": 20}]
從返回結果可以看出data_json字符串中lang數據類型從元祖變成了列表。
還可以對列印的json字符進行美化,可以使用如下Python語句。
data_json = json.dumps(data,sort_keys = True, indent=2 )
print( data_json )
輸出結果為
{
"age": 20,
"lang": [
"python",
"java"
],
"name": "wangwu"
}
如果要對輸出json字符串去除無用的空白字符,可以使用如下Python語句。
data_json = json.dumps(data,sort_keys = True,separators=(',',':') )
print( data_json )
輸出結果為:
{"age":20,"lang":["python","java"],"name":"wangwu"}
4、反序列化操作實例,把JSON格式字符串轉換為Python對象
new_data = json.loads(data_json )
print(new_data )
print(type(new_data))
輸出結果為:
{'age': 20, 'lang': ['python', 'java'], 'name': 'wangwu'}
<class 'dict'>
從返回結果可以看出,解碼後並沒有將原始數據data_json的lang數據還原成元祖,而是還原成了列表。
自定義對象的序列化
如果是類對象,是不是可以可以直接用json.dumps(obj)序列化對象呢?答案是不可以的,需要在類對象裡編寫轉換函數。
例子:自定義對象的序列化
import json
class Man(object):
def __init__(self, name, age ):
self.name = name
self.age = age
def obj2json(obj):
return {
"name" : obj.name,
"age" : obj.age
}
man = Man('tom' , 21)
jsonDataStr = json.dumps( man , default=obj2json)
print( jsonDataStr )
運行腳本得到以下輸出結果:
{"name": "tom", "age": 21}
json.dumps()函數中的可選參數default就是把任意一個對象變成一個可序列為JSON的對象,我們只需要為Man專門寫一個轉換函數,再把函數傳進去即可。
通過一種簡單的方式,用lambda方式來轉換任意一個類對象為JSON形式。
jsonDataStr = json.dumps(man, default=lambda obj: obj.__dict__)
lambda obj: obj.__dict__會將任意的對象的屬性,轉換成字典的方式。同樣的道理,如果要將JSON對象反序列化,也需要寫個反序列化函數來轉換。
json.loads(json_str, object_hook=handle)
import json
class Man(object):
def __init__(self, name, age ):
self.name = name
self.age = age
def obj2json(obj):
return {
"name" : obj.name,
"age" : obj.age
}
def handle( obj ):
print( type(obj))
return Man(obj['name'] , obj['age'])
man = Man('tom' , 21)
jsonDataStr = json.dumps( man , default=obj2json)
jsonObj = json.loads(jsonDataStr, object_hook=handle )
在本例中編寫反序列化函數handle()把JSON字符串轉換成Python類的對象。
留言回覆你用Python做過哪些有趣的應用項目,我們會在留言中隨機抽取一位讀者免費送出北京大學出版社出版的《Python 3 數據分析與機器學習實戰》圖書一本。
文章節選自北京大學出版社出版的《Python 3 數據分析與機器學習實戰》,本書現在京東參加滿100減50的活動,點擊閱讀原文購書有優惠~