技術頻道導航
HTML/CSS
.NET技術
IIS技術
PHP技術
Js/JQuery
Photoshop
Fireworks
服務器技術
操作系統(tǒng)
網(wǎng)站運營

贊助商

分類目錄

贊助商

最新文章

搜索

5種方法Python將JSON轉換為自定義Python對象/類

作者:admin    時間:2021-12-28 9:58:32    瀏覽:

本文將介紹Phyton如何將JSON數(shù)據(jù)轉換為自定義Python對象,即,解析并將JSON轉換為Python類。

Python使用json.load() 和 json.loads() 方法從文件或字符串加載 JSON 數(shù)據(jù)時,它會返回一個dict。如果我們將 JSON 數(shù)據(jù)直接加載到我們的自定義類型中,我們可以更輕松地操作和使用它。有多種方法可以實現(xiàn)這一點,你可以選擇你認為對你的問題更有用的方式。讓我們看看如何將 JSON 字符串反序列化為自定義 Python 對象。

Python如何將JSON 轉換為自定義Python對象
Python如何將JSON轉換為自定義Python對象

使用namedtuple和object_hook將JSON轉換為自定義Python對象

我們可以使用json.loads()和json.load()方法中的object_hook參數(shù),這是一個可選函數(shù),將使用任何對象文字解碼的結果(字典dict)調(diào)用,所以當我們執(zhí)行json.loads()時,object_hook的返回值將用字典dict代替。使用此功能,我們可以實現(xiàn)自定義解碼器。

正如我們所知json.load()json.loads()方法將 JSON 轉換為dict對象,因此我們需要創(chuàng)建一個自定義函數(shù),我們可以在其中轉換dict為自定義 Python 類型。并將這個新創(chuàng)建的函數(shù)傳遞給json.loads方法的object_hook參數(shù)。所以我們可以在解碼JSON時獲得自定義類型。

namedtuple是集合模塊下的類。與字典類型對象一樣,它包含鍵并映射到某些值。在這種情況下,我們可以使用鍵和索引訪問元素。

讓我們先看一個簡單的例子,然后我們才能進入實際的例子。在此示例中,我們將學生JSON數(shù)據(jù)轉換為自定義學生類類型。

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

如你所見,我們將 JSON 字符串格式的 JSON 數(shù)據(jù)轉換為自定義 Python 對象 Student?,F(xiàn)在,我們可以使用 dot(.) 運算符訪問其成員。

現(xiàn)在,讓我們看看使用復雜 Python 對象的實時場景。我們需要將自定義 Python 對象轉換為 JSON。此外,我們想從 JSON 構造一個自定義的 Python 對象。

在這個例子中,我們使用了兩個類StudentMarks。Marks類是Student類的成員。

  • 首先,我們將 Student 類編碼為 JSON 數(shù)據(jù)。
  • 然后,我們使用相同的 JSON 數(shù)據(jù)將其解碼為 Student 類。

現(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 轉換為自定義 Python 對象

我們可以用types.SimpleNamespace作為 JSON 對象的容器。與命名元組解決方案相比,它具有以下優(yōu)勢:

  • 它的執(zhí)行時間更少,因為它沒有為每個對象創(chuàng)建一個類。
  • 它精確而簡單。

在本例中,我們將使用types.SimpleNamespaceobject_hook將 JSON 數(shù)據(jù)轉換為自定義 Python 對象。 

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 類的對象解碼將 JSON 數(shù)據(jù)轉換為自定義 Python 對象 

我們可以使用 json模塊的json.JSONDecoder類來專門進行 JSON 對象解碼,這里我們可以將 JSON 對象解碼為自定義的 Python 類型。

我們需要在一個類中創(chuàng)建一個新函數(shù),該函數(shù)將負責檢查 JSON 字符串中的對象類型,在獲取 JSON 數(shù)據(jù)中的正確類型后,我們可以構建我們的對象。

讓我們看看例子。 

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ù)轉換為自定義 Python 對象

jsonpickle 是一個 Python 庫,旨在處理復雜的 Python 對象。你可以使用 jsonpickle 對復雜的 Python 和 JSON 數(shù)據(jù)進行序列化和反序列化。

Python 內(nèi)置的 JSON 模塊只能處理 Python 原語。對于任何自定義 Python 對象,我們都需要編寫自己的 JSONEncoderDecoder

使用 jsonpickle 我們將執(zhí)行以下操作:

  • 首先,我們將使用 jsonpickle 將 Student 對象編碼為 JSON
  • 然后我們將Student JSON解碼成Student對象

現(xiàn)在,讓我們看看將 JSON 數(shù)據(jù)轉換為自定義 Python 對象的 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

新建一個對象,將結果字典作為map傳遞,將JSON數(shù)據(jù)轉換為自定義的Python對象

正如我們所知json.loads()json.load()方法返回一個dict對象。我們可以通過將dict對象作為參數(shù)傳遞給 Student 對象構造函數(shù)來構造一個新的自定義對象。即,我們可以將dict對象映射到自定義對象。

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

總結

本文通過幾種方法,介紹了Python如何將JSON轉換為自定義Python對象/Python類。

您可能對以下文章也感興趣

標簽: Python  
x