|
|
|
|
|
本文將介紹Phyton如何將JSON數(shù)據(jù)轉(zhuǎn)換為自定義Python對(duì)象,即,解析并將JSON轉(zhuǎn)換為Python類(lèi)。
Python使用json.load() 和 json.loads() 方法從文件或字符串加載 JSON 數(shù)據(jù)時(shí),它會(huì)返回一個(gè)dict
。如果我們將 JSON 數(shù)據(jù)直接加載到我們的自定義類(lèi)型中,我們可以更輕松地操作和使用它。有多種方法可以實(shí)現(xiàn)這一點(diǎn),你可以選擇你認(rèn)為對(duì)你的問(wèn)題更有用的方式。讓我們看看如何將 JSON 字符串反序列化為自定義 Python 對(duì)象。
Python如何將JSON轉(zhuǎn)換為自定義Python對(duì)象
使用namedtuple和object_hook將JSON轉(zhuǎn)換為自定義Python對(duì)象
我們可以使用json.loads()和json.load()方法中的object_hook
參數(shù),這是一個(gè)可選函數(shù),將使用任何對(duì)象文字解碼的結(jié)果(字典dict
)調(diào)用,所以當(dāng)我們執(zhí)行json.loads()
時(shí),object_hook
的返回值將用字典dict
代替。使用此功能,我們可以實(shí)現(xiàn)自定義解碼器。
正如我們所知json.load()
和json.loads()
方法將 JSON 轉(zhuǎn)換為dict
對(duì)象,因此我們需要?jiǎng)?chuàng)建一個(gè)自定義函數(shù),我們可以在其中轉(zhuǎn)換dict
為自定義 Python 類(lèi)型。并將這個(gè)新創(chuàng)建的函數(shù)傳遞給json.loads方法的object_hook參數(shù)。所以我們可以在解碼JSON時(shí)獲得自定義類(lèi)型。
namedtuple是集合模塊下的類(lèi)。與字典類(lèi)型對(duì)象一樣,它包含鍵并映射到某些值。在這種情況下,我們可以使用鍵和索引訪問(wèn)元素。
讓我們先看一個(gè)簡(jiǎn)單的例子,然后我們才能進(jìn)入實(shí)際的例子。在此示例中,我們將學(xué)生JSON數(shù)據(jù)轉(zhuǎn)換為自定義學(xué)生類(lèi)類(lèi)型。
import json
from collections import namedtuple
from json import JSONEncoder
def customStudentDecoder(studentDict):
return namedtuple('X', studentDict.keys())(*studentDict.values())
#Assume you received this JSON response
studentJsonData = '{"rollNumber": 1, "name": "Emma"}'
# Parse JSON into an object with attributes corresponding to dict keys.
student = json.loads(studentJsonData, object_hook=customStudentDecoder)
print("After Converting JSON Data into Custom Python Object")
print(student.rollNumber, student.name)
輸出:
After Converting JSON Data into Custom Python Object
1 Emma
如你所見(jiàn),我們將 JSON 字符串格式的 JSON 數(shù)據(jù)轉(zhuǎn)換為自定義 Python 對(duì)象 Student?,F(xiàn)在,我們可以使用 dot(.) 運(yùn)算符訪問(wèn)其成員。
現(xiàn)在,讓我們看看使用復(fù)雜 Python 對(duì)象的實(shí)時(shí)場(chǎng)景。我們需要將自定義 Python 對(duì)象轉(zhuǎn)換為 JSON。此外,我們想從 JSON 構(gòu)造一個(gè)自定義的 Python 對(duì)象。
在這個(gè)例子中,我們使用了兩個(gè)類(lèi)Student和Marks。Marks類(lèi)是Student類(lèi)的成員。
現(xiàn)在讓我們看看例子。
import json
from collections import namedtuple
from json import JSONEncoder
class Student:
def __init__(self, rollNumber, name, marks):
self.rollNumber, self.name, self.marks = rollNumber, name, marks
class Marks:
def __init__(self, english, geometry):
self.english, self.geometry = english, geometry
class StudentEncoder(JSONEncoder):
def default(self, o):
return o.__dict__
def customStudentDecoder(studentDict):
return namedtuple('X', studentDict.keys())(*studentDict.values())
marks = Marks(82, 74)
student = Student(1, "Emma", marks)
# dumps() produces JSON in native str format. if you want to writ it in file use dump()
studentJson = json.dumps(student, indent=4, cls=StudentEncoder)
print("Student JSON")
print(studentJson)
# Parse JSON into an object with attributes corresponding to dict keys.
studObj = json.loads(studentJson, object_hook=customStudentDecoder)
print("After Converting JSON Data into Custom Python Object")
print(studObj.rollNumber, studObj.name, studObj.marks.english, studObj.marks.geometry)
輸出:
Student JSON
{
"rollNumber": 1,
"name": "Emma",
"marks": {
"english": 82,
"geometry": 74
}
}
After Converting JSON Data into Custom Python Object
1 Emma 82 74
使用 types.SimpleNamespace 和 object_hook 將 JSON 轉(zhuǎn)換為自定義 Python 對(duì)象
我們可以用types.SimpleNamespace
作為 JSON 對(duì)象的容器。與命名元組解決方案相比,它具有以下優(yōu)勢(shì):
在本例中,我們將使用types.SimpleNamespace
和object_hook
將 JSON 數(shù)據(jù)轉(zhuǎn)換為自定義 Python 對(duì)象。
from __future__ import print_function
import json
from json import JSONEncoder
try:
from types import SimpleNamespace as Namespace
except ImportError:
# Python 2.x fallback
from argparse import Namespace
class Student:
def __init__(self, rollNumber, name, marks):
self.rollNumber, self.name, self.marks = rollNumber, name, marks
class Marks:
def __init__(self, english, geometry):
self.english, self.geometry = english, geometry
class StudentEncoder(JSONEncoder):
def default(self, o): return o.__dict__
marks = Marks(82, 74)
student = Student(1, "Emma", marks)
# dumps() produces JSON in native str format. if you want to writ it in file use dump()
studentJsonData = json.dumps(student, indent=4, cls=StudentEncoder)
print("Student JSON")
print(studentJsonData)
# Parse JSON into an custom Student object.
studObj = json.loads(studentJsonData, object_hook=lambda d: Namespace(**d))
print("After Converting JSON Data into Custom Python Object using SimpleNamespace")
print(studObj.rollNumber, studObj.name, studObj.marks.english, studObj.marks.geometry)
輸出:
Student JSON
{
"rollNumber": 1,
"name": "Emma",
"marks": {
"english": 82,
"geometry": 74
}
}
After Converting JSON Data into Custom Python Object using SimpleNamespace
1 Emma 82 74
使用 JSONDecoder 類(lèi)的對(duì)象解碼將 JSON 數(shù)據(jù)轉(zhuǎn)換為自定義 Python 對(duì)象
我們可以使用 json模塊的json.JSONDecoder
類(lèi)來(lái)專(zhuān)門(mén)進(jìn)行 JSON 對(duì)象解碼,這里我們可以將 JSON 對(duì)象解碼為自定義的 Python 類(lèi)型。
我們需要在一個(gè)類(lèi)中創(chuàng)建一個(gè)新函數(shù),該函數(shù)將負(fù)責(zé)檢查 JSON 字符串中的對(duì)象類(lèi)型,在獲取 JSON 數(shù)據(jù)中的正確類(lèi)型后,我們可以構(gòu)建我們的對(duì)象。
讓我們看看例子。
import json
class Student(object):
def __init__(self, rollNumber, name, marks):
self.rollNumber = rollNumber
self.name = name
self.marks = marks
def studentDecoder(obj):
if '__type__' in obj and obj['__type__'] == 'Student':
return Student(obj['rollNumber'], obj['name'], obj['marks'])
return obj
studentObj = json.loads('{"__type__": "Student", "rollNumber":1, "name": "Ault kelly", "marks": 78}',
object_hook=studentDecoder)
print("Type of decoded object from JSON Data")
print(type(studentObj))
print("Student Details")
print(studentObj.rollNumber, studentObj.name, studentObj.marks)
輸出:
Type of decoded object from JSON Data
<class '__main__.Student'>
Student Details
1 Ault kelly 78
使用 jsonpickle 模塊將 JSON 數(shù)據(jù)轉(zhuǎn)換為自定義 Python 對(duì)象
jsonpickle 是一個(gè) Python 庫(kù),旨在處理復(fù)雜的 Python 對(duì)象。你可以使用 jsonpickle 對(duì)復(fù)雜的 Python 和 JSON 數(shù)據(jù)進(jìn)行序列化和反序列化。
Python 內(nèi)置的 JSON 模塊只能處理 Python 原語(yǔ)。對(duì)于任何自定義 Python 對(duì)象,我們都需要編寫(xiě)自己的 JSONEncoder 和 Decoder。
使用 jsonpickle 我們將執(zhí)行以下操作:
現(xiàn)在,讓我們看看將 JSON 數(shù)據(jù)轉(zhuǎn)換為自定義 Python 對(duì)象的 jsonpickle 示例。
import json
import jsonpickle
from json import JSONEncoder
class Student(object):
def __init__(self, rollNumber, name, marks):
self.rollNumber = rollNumber
self.name = name
self.marks = marks
class Marks(object):
def __init__(self, english, geometry):
self.english = english
self.geometry = geometry
marks = Marks(82, 74)
student = Student(1, "Emma", marks)
print("Encode Object into JSON formatted Data using jsonpickle")
studentJSON = jsonpickle.encode(student)
print(studentJSON)
print("Decode and Convert JSON into Object using jsonpickle")
studentObject = jsonpickle.decode(studentJSON)
print("Object type is: ", type(studentObject))
print("Student Details")
print(studentObject.rollNumber, studentObject.name, studentObject.marks.english, studentObject.marks.geometry)
輸出:
Encode Object into JSON formatted Data using jsonpickle
{"marks": {"english": 82, "geometry": 74, "py/object": "__main__.Marks"}, "name": "Emma", "py/object": "__main__.Student", "rollNumber": 1}
Decode JSON formatted Data using jsonpickle
1 Emma 82 74
新建一個(gè)對(duì)象,將結(jié)果字典作為map傳遞,將JSON數(shù)據(jù)轉(zhuǎn)換為自定義的Python對(duì)象
正如我們所知json.loads()
和json.load()
方法返回一個(gè)dict
對(duì)象。我們可以通過(guò)將dict
對(duì)象作為參數(shù)傳遞給 Student 對(duì)象構(gòu)造函數(shù)來(lái)構(gòu)造一個(gè)新的自定義對(duì)象。即,我們可以將dict
對(duì)象映射到自定義對(duì)象。
import json
from json import JSONEncoder
class Student(object):
def __init__(self, rollNumber, name, *args, **kwargs):
self.rollNumber = rollNumber
self.name = name
class StudentEncoder(JSONEncoder):
def default(self, o):
return o.__dict__
student = Student(1, "Emma")
# encode Object it
studentJson = json.dumps(student, cls=StudentEncoder, indent=4)
#Deconde JSON
resultDict = json.loads(studentJson)
print("Converting JSON into Python Object")
studentObj = Student(**resultDict)
print("Object type is: ", type(studentObj))
print("Student Details")
print(studentObj.rollNumber, studentObj.name)
輸出:
Converting JSON into Python Object
Object type is: <class '__main__.Student'>
Student Details
1 Emma
總結(jié)
本文通過(guò)幾種方法,介紹了Python如何將JSON轉(zhuǎn)換為自定義Python對(duì)象/Python類(lèi)。