JSON'u Python Nesnesine dönüştürme

JSON'u Python Nesnesine dönüştürme

Python'un json kütüphane, verileri JSON biçiminde kodlamak ve kodunu çözmek için birçok yardımcı programa sahiptir. özellikle, json.load() yöntem, dosya olarak okunan bir JSON'un kodunu çözer ve json.loads() dize olarak okunan bir JSON'un kodunu çözün. Genel olarak, JSON dosyalarının kodu çözülürken veriler Python sözlüklerine dönüştürülür, ancak parametre kullanılarak özel bir nesneye dönüştürülmesi mümkündür. object_hook.

Örneğin, aşağıdaki JSON nesnesine sahip olduğunuzu varsayalım:

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

ve aşağıdaki sınıf:

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")

eğer ararsak json.loads() ile User gibi object_hook parametre, User.__init__() yöntem, JSON'un karşılık gelen değeriyle çağrılacak dict girdi olarak.

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]

Peki ya iç içe geçmiş bir JSON'unuz varsa?

json.loads() aslında çağırır object_hook dizeden tam olarak oluşturulmuş bir JSON nesnesini her okuduğunda işlev görür. Şu kaynaktan döndürülen aşağıdaki JSON'u göz önünde bulundurun: Rastgele Kullanıcı Oluşturucu API'sı

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"
        }"""

Ne olduğunu görmek için her adımda kodu çözülmüş JSON'u yazdıralım:

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() çağırır object_hook tam olarak oluşturulmuş bir JSON'u her okuduğunda, yani bir parantez çiftini her kapattığında işlev görür {}. Ardından, sonucu kullanarak tüm JSON nesnesini oluşturur. object_hook işlev – not edin None (dönüş değeri print) son yazdırılan satırda.

Bu sorun için iki geçici çözüm göstereceğiz. Birincisi, bizim User.__init__() yöntem girdiye göre daha esnektir. Bunu kullanarak yapacağız __dict__ bağlanmak. Her Python nesnesinin bir __dict__ her özelliğin adını ve değerini tutan özellik. Bizim değiştirilmiş __init__() yöntem bu sözlüğü güncelleyecektir:

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}")

En iyi uygulamalar, endüstri tarafından kabul edilen standartlar ve dahil edilen hile sayfası ile Git'i öğrenmek için uygulamalı, pratik kılavuzumuza göz atın. Googling Git komutlarını durdurun ve aslında öğrenmek o!

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

Başka bir olası geçici çözüm, collections.namedtuple sınıf:

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]

nerede namedtuple('User', input.keys()) adında bir Tuple alt sınıfı oluşturur. User öznitelik adları olarak girişin tuşlarıyla ve User(**input) nitelikler için karşılık gelen değerleri atar.

Zaman Damgası:

Den fazla Yığın kötüye kullanımı