از طریق منوی جستجو مطلب مورد نظر خود در وبلاگ را به سرعت پیدا کنید
روش تبدیل JSON به آبجکت پایتون
روش تبدیل JSON به آبجکت پایتون
پایتون json
کتابخانه ابزارهای بسیاری برای رمزگذاری و رمزگشایی داده ها در قالب JSON دارد. به طور خاص، json.load()
متد یک JSON خوانده شده به عنوان فایل را رمزگشایی می کند و json.loads()
یک JSON خوانده شده به عنوان یک رشته را رمزگشایی کنید. به طور کلی، هنگام رمزگشایی فایلهای JSON، دادهها به دیکشنری پایتون تبدیل میشوند، اما امکان تبدیل آن به یک شی سفارشی با استفاده از پارامتر وجود دارد. object_hook
.
به عنوان مثال، فرض کنید شی JSON زیر را دارید:
json_obj = """{
"name" : "Felipe",
"email" : "(email protected)",
"age" : 29
}"""
و کلاس زیر:
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")
اگر تماس بگیریم json.loads()
با User
به عنوان object_hook
پارامتر، User.__init__()
متد با JSON مربوطه فراخوانی خواهد شد dict
به عنوان ورودی
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)
اما اگر یک JSON تو در تو داشته باشید چه؟
json.loads()
در واقع به object_hook
تابع هر بار که یک شیء JSON کاملاً تشکیل شده را از رشته می خواند. JSON زیر را در نظر بگیرید Random User Generator 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"
}"""
اجازه دهید print JSON رمزگشایی شده در هر مرحله برای دیدن آنچه اتفاق می افتد:
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'}
بنابراین json.loads()
تماس می گیرد object_hook
تابع هر بار که یک JSON کاملاً تشکیل شده را می خواند، یعنی هر بار که یک جفت براکت را می بندد. {}
. سپس، کل شی JSON را با استفاده از نتیجه ایجاد می کند object_hook
تابع – توجه داشته باشید None
(مقدار بازگشتی از print
) در آخرین خط چاپ شده.
ما دو راه حل برای این موضوع نشان خواهیم داد. اولین مورد این است که ما را اصلاح کنیم User.__init__()
روشی که نسبت به ورودی انعطاف پذیرتر باشد. ما این کار را با استفاده از __dict__
صفت. هر شی پایتون دارای یک است __dict__
ویژگی که نام و مقدار هر ویژگی را در خود جای می دهد. ما اصلاح شد __init__()
روش این فرهنگ لغت را به روز می کند:
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}")
User Ian Walters, age 75, email (email protected)
یکی دیگر از راه حل های ممکن استفاده از collections.namedtuple
کلاس:
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)
جایی که namedtuple('User', input.keys())
یک زیر کلاس تاپل به نام ایجاد می کند User
با کلیدهای ورودی به عنوان نام ویژگی ها، و User(**input)
مقادیر مربوطه را برای صفات اختصاص می دهد.
(برچسبها به ترجمه)# python
منتشر شده در 1403-01-02 09:02:03