Cara mengonversi JSON ke Objek Python

Cara mengonversi JSON ke Objek Python

Python json perpustakaan memiliki banyak utilitas untuk menyandikan dan mendekode data dalam format JSON. Secara khusus, json.load() metode menerjemahkan JSON yang dibaca sebagai file, dan metode json.loads() mendekode JSON yang dibaca sebagai string. Secara umum, saat mendekode file JSON, data dikonversi ke kamus Python, tetapi dimungkinkan untuk mengonversinya menjadi objek khusus dengan menggunakan parameter object_hook.

Misalnya, Anda memiliki objek JSON berikut:

json_obj = """{
  "name" : "Felipe",
  "email" : "[email protected]",
  "age" : 29
}"""

dan kelas berikut:

class User():
  name : str
  email : str
  age : int
  def __init__(self, input):
      self.name = input.get("name")
      self.email = input.get("email")
      self.age = input.get("age")

Jika kita menelepon json.loads() dengan User sebagai object_hook parameter, User.__init__() metode akan dipanggil dengan JSON yang sesuai dict sebagai masukan.

import json

user = json.loads(json_obj, object_hook = User)
print(f"User {user.name}, age {user.age}, email {user.email}")
User Felipe, age 29, email [email protected]

Namun bagaimana jika Anda memiliki JSON bersarang?

json.loads() sebenarnya memanggil object_hook berfungsi setiap kali ia membaca objek JSON yang terbentuk sepenuhnya dari string. Pertimbangkan JSON berikut, yang dikembalikan dari API Generator Pengguna Acak

json_obj = """{
            "gender": "male",
            "name": {
                "title": "Mr",
                "first": "Ian",
                "last": "Walters"
            },
            "location": {
                "street": {
                    "number": 3161,
                    "name": "Saddle Dr"
                },
                "city": "Bendigo",
                "state": "Western Australia",
                "country": "Australia",
                "postcode": 4285,
                "coordinates": {
                    "latitude": "-84.7903",
                    "longitude": "-29.1020"
                },
                "timezone": {
                    "offset": "+9:00",
                    "description": "Tokyo, Seoul, Osaka, Sapporo, Yakutsk"
                }
            },
            "email": "[email protected]",
            "login": {
                "uuid": "6ee5b2e8-01c3-4314-8f7f-80059f5dd9ec",
                "username": "lazyzebra585",
                "password": "walter",
                "salt": "afXmogsa",
                "md5": "a40e87023b57a4a60c7cb398584cbac3",
                "sha1": "74caf43400be38cce60a8da2e6d1c367246505c2",
                "sha256": "1becdf34bcc6704726c7e9b38821a5792f9dd0689d30789fb5e099a6e51e860a"
            },
            "dob": {
                "date": "1947-06-06T02:45:41.895Z",
                "age": 75
            },
            "registered": {
                "date": "2003-03-25T00:15:32.791Z",
                "age": 19
            },
            "phone": "06-9388-6976",
            "cell": "0469-101-424",
            "id": {
                "name": "TFN",
                "value": "561493929"
            },
            "picture": {
                "large": "https://randomuser.me/api/portraits/men/32.jpg",
                "medium": "https://randomuser.me/api/portraits/med/men/32.jpg",
                "thumbnail": "https://randomuser.me/api/portraits/thumb/men/32.jpg"
            },
            "nat": "AU"
        }"""

Mari cetak JSON yang didekodekan pada setiap langkah untuk melihat apa yang terjadi:

json.loads(json_obj, object_hook = print)
{'title': 'Mr', 'first': 'Ian', 'last': 'Walters'}
{'number': 3161, 'name': 'Saddle Dr'}
{'latitude': '-84.7903', 'longitude': '-29.1020'}
{'offset': '+9:00', 'description': 'Tokyo, Seoul, Osaka, Sapporo, Yakutsk'}
{'street': None, 'city': 'Bendigo', 'state': 'Western Australia', 'country': 'Australia', 'postcode': 4285, 'coordinates': None, 'timezone': None}
{'uuid': '6ee5b2e8-01c3-4314-8f7f-80059f5dd9ec', 'username': 'lazyzebra585', 'password': 'walter', 'salt': 'afXmogsa', 'md5': 'a40e87023b57a4a60c7cb398584cbac3', 'sha1': '74caf43400be38cce60a8da2e6d1c367246505c2', 'sha256': '1becdf34bcc6704726c7e9b38821a5792f9dd0689d30789fb5e099a6e51e860a'}
{'date': '1947-06-06T02:45:41.895Z', 'age': 75}
{'date': '2003-03-25T00:15:32.791Z', 'age': 19}
{'name': 'TFN', 'value': '561493929'}
{'large': 'https://randomuser.me/api/portraits/men/32.jpg', 'medium': 'https://randomuser.me/api/portraits/med/men/32.jpg', 'thumbnail': 'https://randomuser.me/api/portraits/thumb/men/32.jpg'}
{'gender': 'male', 'name': None, 'location': None, 'email': '[email protected]', 'login': None, 'dob': None, 'registered': None, 'phone': '06-9388-6976', 'cell': '0469-101-424', 'id': None, 'picture': None, 'nat': 'AU'}

So json.loads() memanggil object_hook berfungsi setiap kali ia membaca JSON yang terbentuk sepenuhnya, yaitu setiap kali ia menutup pasangan braket {}. Kemudian, ia membuat seluruh objek JSON dengan menggunakan hasil dari object_hook fungsi โ€“ perhatikan None (nilai kembalian dari print) pada baris terakhir yang dicetak.

Kami akan menunjukkan dua solusi untuk masalah ini. Yang pertama adalah memodifikasi kita User.__init__() metode menjadi lebih fleksibel sehubungan dengan input. Kami akan melakukan ini menggunakan __dict__ atribut. Setiap objek Python memiliki a __dict__ atribut yang menyimpan nama dan nilai setiap atribut. Kami dimodifikasi __init__() metode akan memperbarui kamus ini:

class User():
  def __init__(self, input):
      self.__dict__.update(input)

user = json.loads(json_obj, object_hook = User)
print(f"User {user.name.first} {user.name.last}, age {user.dob.age}, email {user.email}")

Lihat panduan praktis dan praktis kami untuk mempelajari Git, dengan praktik terbaik, standar yang diterima industri, dan termasuk lembar contekan. Hentikan perintah Googling Git dan sebenarnya belajar itu!

User Ian Walters, age 75, email [email protected]

Solusi lain yang mungkin dilakukan adalah dengan menggunakan collections.namedtuple kelas:

from collections import namedtuple

def create_user(input):
    User = namedtuple('User', input.keys())
    return User(**input)
    
user = json.loads(json_obj, object_hook=create_user)
print(f"User {user.name.first} {user.name.last}, age {user.dob.age}, email {user.email}")
User Ian Walters, age 75, email [email protected]

dimana namedtuple('User', input.keys()) membuat subkelas Tuple yang disebut User dengan kunci input sebagai nama atribut, dan User(**input) memberikan nilai yang sesuai untuk atribut.

Stempel Waktu:

Lebih dari penyalahgunaan