کتابخانه json در پایتون
کتابخانهٔ استاندارد json در پایتون ابزاری ساده، سبک و متداول برای تبدیل دادههای پایتون به رشتهٔ JSON و برعکس است. JSON (JavaScript Object Notation) فرمت متنیِ نسبتاً خوانایی است که در ارتباطات وب، ذخیرهسازی پیکربندی و تبادل داده بین سرویسها بسیار پرکاربرد است. در این مقاله به توابع اصلی، نکات عملی، نمونههای کد واقعی و تکنیکهای پیشرفته میپردازیم.
توابع و کلاسهای اصلی
| تابع / کلاس | کاربرد |
|---|---|
| json.dumps | تبدیل شی پایتون به رشتهٔ JSON |
| json.dump | نوشتن JSON در فایل |
| json.loads | تبدیل رشتهٔ JSON به شی پایتون |
| json.load | خواندن JSON از فایل |
| json.JSONEncoder | سفارشیسازی سریالسازی |
| json.JSONDecoder | سفارشیسازی دِسریالسازی |
مثال پایه — خواندن و نوشتن JSON با UTF-8
import json
data = {
"name": "علی",
"age": 30,
"skills": ["python", "django"]
}
# تبدیل به رشتهٔ JSON با حفظ یونیکد فارسی
json_str = json.dumps(data, ensure_ascii=False, indent=2)
# ذخیره در فایل با کدگذاری UTF-8
with open("data.json", "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)در این کد از ensure_ascii=False استفاده شده تا کاراکترهای غیرلاتین (مثلاً فارسی) به صورت خوانا در فایل ذخیره شوند. پارامتر indent برای زیبا سازی خروجی (pretty-print) است. هنگام بازخوانی کافی است از json.load یا json.loads استفاده کنید.
سریالسازی اشیاء سفارشی
ساختار JSON از انواع پایهای پایتون مانند dict، list، str، int، float، bool و None پشتیبانی میکند. برای انواع دلخواه (مثلاً کلاسها، datetime، Decimal یا set) نیاز به تبدیل دستی یا پیادهسازی JSONEncoder دارید.
import json
from dataclasses import dataclass
from datetime import datetime
@dataclass
class Person:
name: str
born: datetime
def person_encoder(obj):
if isinstance(obj, Person):
return {"__type__": "Person", "name": obj.name, "born": obj.born.isoformat()}
if isinstance(obj, datetime):
return obj.isoformat()
raise TypeError(f"Type {type(obj)} not serializable")
def person_decoder(d):
if "__type__" in d and d["__type__"] == "Person":
return Person(name=d["name"], born=datetime.fromisoformat(d["born"]))
return d
p = Person("مریم", datetime(1990, 5, 17))
s = json.dumps(p, default=person_encoder, ensure_ascii=False)
obj = json.loads(s, object_hook=person_decoder)در این مثال تابع default (اینجا person_encoder) به json.dumps میگوید که چگونه اشیاء نامأنوس را تبدیل کند. از object_hook در json.loads برای بازسازی شیٔ Person استفاده شده است. این الگو برای انواع پیچیده و تاریخها کاربردی و امن است.
نمونهٔ خطای متداول و راهحل
import json
data = {"items": {1, 2, 3}} # set قابل سریالسازی مستقیم نیست
json.dumps(data)این کد باعث TypeError میشود چون set به صورت پیشفرض سریالپذیر نیست. راهحل: تبدیل set به list یا استفاده از default برای سریالسازی آن:
json.dumps(data, default=lambda o: list(o) if isinstance(o, set) else TypeError())بهترین روش متناسب با کاربردتان تعیین میشود: اگر ترتیب مهم نیست، list مناسب است. برای رفتارهای پیچیدهتر از JSONEncoder سفارشی بهره ببرید.
بهینهسازی و نکات عملکردی
- برای خروجی کامپکت از separators=(“,”, “:”) استفاده کنید تا فاصلههای غیرضروری حذف شوند.
- در پردازش دادههای بسیار بزرگ از روش جریانی (streaming) با json.dump به همراه فایل باز و نوشتن مرحلهای استفاده کنید یا از کتابخانههایی مثل ijson برای خواندن تَکهتَکه.
- برای عملکرد بهتر در کاربردهای تجاری، از کتابخانههای سریعتر مانند orjson یا ujson استفاده کنید؛ اما مراقب تفاوتهای سازگاری و گزینهها باشید.
- برای متون فارسی همیشه ensure_ascii=False و encoding=’utf-8′ در فایل را تنظیم کنید.
compact = json.dumps(data, separators=(",", ":"), ensure_ascii=False)استفاده از separators خروجی را کوچکتر میکند (حذف فضاهای اضافی)، اینکار در انتقال شبکه یا ذخیرهسازی حجم بالا مفید است.
کار با تاریخها و Decimal
پایتون datetime و Decimal به طور مستقیم سریالپذیر نیستند. معمولاً آنها را به رشتهٔ ISO یا عدد تبدیل میکنند:
import json
from datetime import datetime
from decimal import Decimal
def default(o):
if isinstance(o, datetime):
return o.isoformat()
if isinstance(o, Decimal):
return float(o)
raise TypeError
data = {"t": datetime.now(), "price": Decimal("19.99")}
json.dumps(data, default=default, ensure_ascii=False)تبدیل Decimal به float ممکن است دقت را کم کند؛ در صورت نیاز به دقت مالی بهتر است مقدار را به رشته تبدیل کنید و هنگام بارگذاری بازگردانید.
امنیت و خطاها
- برخلاف بعضی روشها، json.loads بهطور پیشفرض eval یا exec اجرا نمیکند، اما همیشه ورودیهای ناشناس را اعتبارسنجی کنید.
- استفاده از object_hook و default باید با دقت باشد تا دادههای مخرب باعث ایجاد اشیاء ناخواسته نشوند.
- خطای رایج: JSONDecodeError هنگام خواندن فرمت نامناسب؛ استفاده از try/except برای مدیریت آن ضروری است.
موارد کاربردی و مثالهای واقعی
- ارسال/دریافت داده در APIs (REST) — تبدیل dict به JSON و برعکس.
- فایلهای پیکربندی سبک (config.json) — خواندن تنظیمات برنامه.
- لاگها و ذخیرهٔ snapshot از وضعیت برنامه.
- ارتباط بین سرویسهای نوشتهشده با زبانهای مختلف.
جمعبندی و راهنماییهای عملی
کتابخانهٔ json پایتون برای بیشتر نیازها کافی و مناسب است. برای کاربردهای خاص: از ensure_ascii=False برای زبانهای غیرلاتین استفاده کنید، با default و object_hook اشیاء پیچیده را مدیریت کنید، و برای دادههای حجیم یا نیاز به سرعت بیشتر به گزینههایی مثل orjson فکر کنید. همیشه ورودیها را اعتبارسنجی کنید و هنگام سریالسازی دقت و سازگاری دادهها را رعایت کنید.
آیا این مطلب برای شما مفید بود ؟




