کتابخانه ی json پایتون
جی سان چست؟
جی سان فرمتی استاندارد برای تبادل داده است. جی سان از جاوا اسکریپت الهام گرفته است. فرمت جی سان به صورت string یا text است. Json مخفف JavaScript Object Notation است.
نحو json
مقادیر در json به صورت کلید-مقدار نوشته می شوند. json به دیکشنری های پایتون بسیار شباهت دارد. پایتون از json پشتیبانی می کند و کتابخانه ی توکاری برای کار با آن فراهم آورده است.
کتابخانه ی json پایتون
برای استفاده از کتابخانه ی json در پایتون، باید این کتابخانه به برنامه اضافه شود
import json
چرا از json استفاده می کنیم؟
همانطور که قبلا گفته شد json فرمتی استاندارد برای تبادل داده است. این تبادل داده ممکن است بین سیستم ها ی مختلفی اتفاق بیفتد. فرض کنید بخواهیم یک دیکشنری را در یک فایل ذخیره کنیم
my_dictionary = {
'name': 'Reganto',
'age': 25
}
with open('my_file', 'w') as f:
f.write(my_dictionary)
خروجی به صورت زیر خواهد بود:
TypeError: write() argument must be str, not Sample
از طرف دیگر فرض کنید بخواهیم یک رشته را به یک دیکشنری تبدیل کنیم. حالتی را که اشیا پایتونی به اشیا جی سانی تبدیل می شوند، Encoding یا Serialization و حالتی را که اشیا جی سانی به اشیا پایتونی تبدیل می شوند، Decoding یا Deserialization می گویند.
پایتون به جی سان(Encoding)
کتابخانه ی json تبدیل های زیر را بر روی اشیا پایتونی در فرایند encoding انجام می دهد.
Python | JSON |
---|---|
dict | object |
list | array |
unicode | string |
number-int, long | number-int |
float | number-real |
True | True |
False | False |
None | null |
فرایند encoding (تبدیل اشیا پایتونی به اشیا جی سانی) توسط متد dumps از کتابخانه ی json انجام می شود. این متد اشیا پایتونی را به فرمت رشته ای جی سانی تبدیل می کند.
یک مثال برای encoding :
import json
my_dictionary = {
'name': 'Reganto',
'age': 25
}
# Check type of my_dictionary
print(type(my_dictionary))
# Encode my_dictionary
encoded_obj = json.dumps(my_dictionary)
# Check type of encoded_obj
print(type(encoded_obj))
# Print encoded_obj
print(encoded_obj)
خروجی:
<class 'dict'>
<class 'str'>
{"name": "Reganto", "age": 25}
اگر بخواهیم پس از انجام فرایند encoding نتیجه را در یک فایل ذخیره کنیم، از متد dump کتابخانه ی json استفاده می کنیم.
import json
my_dictionary = {
'name': 'Reganto',
'age': 25
}
with open('json_file.json', 'w') as f:
json.dump(my_dictionary, f)
حالا فایل json_file.json
را باز کنید. می بینید که دیکشنری به صورت یک رشته جی سانی در آن ذخیره شده است.
جی سان به پایتون(Decoding)
در فرایند decoding (تبدیل اشیا جی سانی به اشیا پایتونی) تبدیل های زیر انجام می شود:
JSON | Python |
---|---|
object | dict |
array | list |
string | unicode |
number-int | number-int, long |
number-real | float |
True | True |
False | False |
null | None |
فرایند decoding با استفاده از متد loads کتابخانه json انجام می شود.
مثال:
import json
my_variable = '{"name": "Reganto", "age": 25}'
# Check type of my_variable
print(type(my_variable))
# Decode my_variable
decoded_obj = json.loads(my_variable)
# Check type of decoded_obj
print(type(decoded_obj))
# Print decoded object
print(decoded_obj)
خروجی:
<class 'str'>
<class 'dict'>
{'name': 'Reganto', 'age': 25}
تجزیه فایل های json در پایتون(Decoding Json File)
قبلا با استفاده از متد dump عمل encoding را انجام دادیم و نتیجه را در فایل json_file.json
ذخیره کردیم. حالا با استفاده از متد load عکس این عمل را انجام می دهیم و رشته جی سانی را از فایل می خوانیم و به شی پایتونی تبدیل می کنیم(decoding).
مثال:
import json
with open('json_file.json') as f:
data = json.load(f)
# Check type of data
print(type(data))
# Print data
print(data)
نکته : تابع open به صورت پیش فرض فایل را در حالت خواندنی باز می کند بنابراین از ذکر آرگومان دوم در اینجا خودداری کردیم اما می توانستیم آرگومان دوم را به صورت صریح با 'r'
مشخص کنیم. خروجی :
<class 'dict'>
{'name': 'Reganto', 'age': 25}
فشرده سازی در عمل Encoding
در عمل encoding می توانیم اندازه فایل جی سان خروجی را کاهش دهیم. بدین منظور از آرگومان separators در متد های dump و dumps استفاده می کنیم.
مثال :
import json
my_data = {'status': 'ok', 'numbers': [1, 2 ,3 ,4 ,5 ,6, 7, 8, 9]}
with open('json_file.json', 'w') as f:
json.dump(my_data, f, separators=(',', ':'))
آرگومان separators کاراکتر ,
را برای لیست ها و کاراکتر :
را برای دیشکنری ها مشخص می کند و فضاهای خالی را از بین می برد.
حالا با مراجعه به شل از فایل ایجاد شده stat می گیریم.
stat json_file.json
خروجی دستور stat :
File: json_file.json
Size: 45 Blocks: 8 IO Block: 4096 regular file
Device: 801h/2049d Inode: 131088 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1000/ reganto) Gid: ( 1000/ reganto)
Access: 2019-07-31 12:59:50.340608484 +0430
Modify: 2019-07-31 12:59:43.136387337 +0430
Change: 2019-07-31 12:59:43.136387337 +0430
Birth: -
و محتوای فایل به صورت زیر است:
{"status":"ok","numbers":[1,2,3,4,5,6,7,8,9]}
همانطور که مشاهده می کنید اندازه فایل 45 بیت است و دیکشنری به صورت فشرده شده با حذف تمام فضا های خالی به صورت رشته ای جی سانی در فایل json_file.json
ذخیره(encode) شده است.
اگر همین مثال را بدون آرگومان separators دوباره انجام دهیم،تفاوت را خواهیم دید.
import json
my_data = {'status': 'ok', 'numbers': [1, 2 ,3 ,4 ,5 ,6, 7, 8, 9]}
with open('json_file.json', 'w') as f:
json.dump(my_data, f)
پس از اجرای برنامه، محتوای فایل به صورت زیر است:
{"status": "ok", "numbers": [1, 2, 3, 4, 5, 6, 7, 8, 9]}
دوباره از فایل خروجی stat می گیریم.
stat json_file.json
خروجی:
File: json_file.json
Size: 56 Blocks: 8 IO Block: 4096 regular file
Device: 801h/2049d Inode: 131088 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1000/ reganto) Gid: ( 1000/ reganto)
Access: 2019-07-31 13:07:02.649878802 +0430
Modify: 2019-07-31 13:06:04.708100217 +0430
Change: 2019-07-31 13:06:04.708100217 +0430
Birth: -
همانطور که مشاهده می کنید اندازه فایل به 56 بیت افزیش یافته است!
زیبا سازی خروجی json
با استفاده از آرگومان indent می توانیم خروجی encode شده را فرمت بندی کنیم
مثال:
import json
my_data = {'name': 'Reganto', 'age': 25}
encoded_formatted_obj = json.dumps(my_data, indent=4)
print(encoded_formatted_obj)
خروجی:
{
"name": "Reganto",
"age": 25
}
متغیر my_data
پس از encode شدن، توسط آرگومان indent فرمت بندی می شود. مقدار این متغیر را تغییر دهید تا با اثر آن بیشتر آشنا شوید.
مرتب سازی خروجی json
آرگومان sort_keys خروجی decode شده را بر اساس کلید های دیکشنری به صورت صعودی مرتب می کند.
مثال:
import json
my_data = {'c': 1, 'd': 2, 'b': 4, 'a': 3}
encoded_formatted_sorted_obj = json.dumps(my_data, indent=4, sort_keys=True)
print(encoded_formatted_sorted_obj)
خروجی :
{
"a": 3,
"b": 4,
"c": 1,
"d": 2
}
و درنهایت با یک مثال کاربردی این مطلب را تمام می کنیم. فرض کنید بخواهیم یک API را فراخوانی کنیم. اکثر Api ها به صورت json به درخواست ها پاسخ می دهند. اگر بخواهیم از پاسخ Api استفاده کنیم باید پاسخ را که از نوع json است به دیکشنری پایتونی تبدیل کنیم(دیکد)
نکته برای استفاده از Api باید کتابخانه ی requests از قبل نصب باشد. می توانید با دستور زیر این کتابخانه را نصب کنید
pip install requests
مثال :
import requests
response = requests.get('https://jsonplaceholder.typicode.com/todos/1')
# Check type of response
print(type(response.text))
# Print response
print(response.text)
خروجی:
<class 'str'>
{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
}
همانطور که می بینید بدنه پاسخ از نوع رشته جی سونی است. پس برای کار با این پاسخ باید آن را به دیکشنری تبدیل کنیم. برای این کار دو روش وجود دارد. اول استفاده از کتابخانه ی json و دیکد کردن پاسخ است.
مثال:
import json
import requests
# Call Api
json_response = requests.get('https://jsonplaceholder.typicode.com/todos/1')
# Decode response body
decoded_response = json.loads(json_response.text)
# Print decoded response
print(decoded_response)
# Print type of decoded_response
print(type(decoded_response))
print(decoded_response.get('id'))
البته راه دوم ساده تر است. برای تبدیل پاسخ جی سانی به دیکشنری پایتونی می توانیم از متد json پاسخ استفاده کنیم.
مثال:
import requests
# Call Api
json_response = requests.get('https://jsonplaceholder.typicode.com/todos/1')
# Decode response body
decoded_response = json_response.json()
# Print type of decode response
print(type(decoded_response))
print(decoded_response['id'])