Kuidas teisendada JSON Pythoni objektiks
Pythoni oma json
raamatukogul on palju utiliite andmete kodeerimiseks ja dekodeerimiseks JSON-vormingus. Eelkõige, json.load()
meetod dekodeerib failina loetud JSON-i ja json.loads()
dekodeerida stringina loetud JSON-i. Üldiselt teisendatakse JSON-failide dekodeerimisel andmed Pythoni sõnaraamatuteks, kuid parameetri abil on võimalik need kohandatud objektiks teisendada. object_hook
.
Oletame näiteks, et teil on järgmine JSON-objekt:
json_obj = """{
"name" : "Felipe",
"email" : "[email protected]",
"age" : 29
}"""
ja järgmine klass:
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")
Kui helistame json.loads()
koos User
kui object_hook
parameeter, User.__init__()
meetodit kutsutakse koos JSON-i vastavaga dict
sisendiks.
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]
Aga mis siis, kui teil on pesastatud JSON?
json.loads()
tegelikult helistab object_hook
funktsioon iga kord, kui see loeb stringist täielikult moodustatud JSON-objekti. Mõelge järgmisele JSON-ile, mis on tagastatud aadressilt Juhusliku kasutaja generaatori API
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"
}"""
Printige igal sammul dekodeeritud JSON, et näha, mis juhtub.
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()
kutsub object_hook
funktsiooni iga kord, kui see loeb täielikult moodustatud JSON-i, st iga kord, kui see sulgude paari sulgeb {}
. Seejärel loob see kogu JSON-objekti, kasutades tulemuse object_hook
funktsioon – pange tähele None
(tagastusväärtus print
) viimasel prinditud real.
Näitame selle probleemi jaoks kahte lahendust. Esimene on muuta meie User.__init__()
sisendi suhtes paindlikum. Teeme seda kasutades __dict__
atribuut. Igal Pythoni objektil on a __dict__
atribuut, mis sisaldab iga atribuudi nime ja väärtust. Meie muudetud __init__()
meetod värskendab seda sõnastikku:
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}")
Tutvuge meie praktilise ja praktilise Giti õppimise juhendiga, mis sisaldab parimaid tavasid, tööstusharus aktsepteeritud standardeid ja kaasas olevat petulehte. Lõpetage Giti käskude guugeldamine ja tegelikult õppima seda!
User Ian Walters, age 75, email [email protected]
Teine võimalik lahendus on kasutada collections.namedtuple
klass:
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]
kus namedtuple('User', input.keys())
loob korteeži alamklassi nimega User
sisendi võtmetega atribuutide nimedena ja User(**input)
määrab atribuutidele vastavad väärtused.