FA-TOOLS — Header Component

کدهای آماده کار با JSON و پایتون

نقشه راه سریع: تسلط بر JSON با پایتون

کدهای آماده کار با JSON و پایتون — تصویر 1

JSON (JavaScript Object Notation) استانداردی سبک و خوانا برای تبادل داده است که به شدت در وب‌سرویس‌ها و APIها محبوبیت دارد. پایتون با ماژول `json` داخلی خود، کار با این فرمت را فوق‌العاده ساده کرده است. در این مقاله جامع، قدم به قدم با کدهای آماده و کاربردی، از مفاهیم اولیه تا ترفندهای پیشرفته، کار با JSON در پایتون را فرا می‌گیرید. آماده‌اید تا داده‌های خود را با قدرت پایتون مدیریت کنید؟

  • تبدیل JSON به پایتون: با `json.loads()` و `json.load()` از رشته یا فایل JSON، آبجکت پایتون بسازید.
  • تبدیل پایتون به JSON: با `json.dumps()` و `json.dump()` داده‌های پایتون را به رشته یا فایل JSON تبدیل کنید.
  • ساختاردهی و زیباسازی: از پارامتر `indent` برای خوانایی بهتر خروجی JSON بهره ببرید.
  • مدیریت خطا: با `try-except` خطاهای رایج مانند `JSONDecodeError` را مدیریت کنید.
  • داده‌های پیچیده: نحوه کار با لیست‌ها، دیکشنری‌های تودرتو و انواع مختلف داده را بیاموزید.
  • موارد کاربردی: از خواندن پاسخ APIها تا ذخیره‌سازی تنظیمات، مثال‌های واقعی را ببینید.

این مقاله راهنمای جامع شما برای کارآمدترین تعامل با JSON در پایتون خواهد بود.

فهرست مطالب

کدهای آماده کار با JSON و پایتون — تصویر 2
  1. مقدمه‌ای بر JSON و چرا پایتون؟
  2. نصب و آماده‌سازی ماژول `json` در پایتون
  3. تبدیل JSON به داده‌های پایتون (Deserialization)
    1. خواندن JSON از یک رشته با `json.loads()`
    2. خواندن JSON از یک فایل با `json.load()`
  4. تبدیل داده‌های پایتون به JSON (Serialization)
    1. تبدیل به رشته JSON با `json.dumps()`
    2. نوشتن JSON در یک فایل با `json.dump()`
  5. کار با ساختارهای پیچیده JSON
    1. دیکشنری‌های تودرتو
    2. لیست دیکشنری‌ها و دیکشنری لیست‌ها
  6. مدیریت خطاها در پردازش JSON
  7. تنظیمات پیشرفته و بهینه‌سازی
    1. زیباسازی خروجی با `indent`
    2. ترتیب کلیدها با `sort_keys`
    3. سفارشی‌سازی سریالایزرها و دی‌سریالایزرها
  8. کاربردهای عملی JSON در پایتون
    1. خواندن پاسخ API
    2. ذخیره‌سازی و بارگذاری تنظیمات
  9. مقایسه توابع اصلی `json` در پایتون
  10. عیب‌یابی سریع (Troubleshooting)
  11. سوالات متداول (FAQ)
  12. نتیجه‌گیری

مقدمه‌ای بر JSON و چرا پایتون؟

کدهای آماده کار با JSON و پایتون — تصویر 3

JSON یا JavaScript Object Notation، یک فرمت استاندارد متنی برای نمایش ساختاریافته داده‌ها است که هم برای انسان‌ها و هم برای ماشین‌ها به‌راحتی قابل خواندن و نوشتن است. این فرمت به‌خاطر سادگی و کارایی بالا، به زبان دِفاکتو (Defacto) برای تبادل داده در APIهای وب و پایگاه‌های داده NoSQL تبدیل شده است. JSON از جفت‌های کلید-مقدار (key-value pairs) تشکیل شده است، بسیار شبیه به دیکشنری‌های پایتون.

پایتون، با فلسفه‌ی “باتری‌ها در جعبه” (Batteries Included) خود، ماژول `json` را به‌صورت توکار (built-in) ارائه می‌دهد. این ماژول ابزارهای قدرتمندی برای تبدیل داده‌های پایتون به فرمت JSON (Serialization) و برعکس (Deserialization) فراهم می‌کند. سهولت استفاده، سینتکس شفاف و سازگاری بالای پایتون با JSON، این زبان را به انتخابی ایده‌آل برای هر توسعه‌دهنده‌ای که با داده‌های JSON سروکار دارد، تبدیل کرده است.

نصب و آماده‌سازی ماژول `json` در پایتون

خبر خوب این است که برای استفاده از ماژول `json` در پایتون، نیازی به نصب هیچ پکیج اضافه‌ای نیست! این ماژول به‌طور پیش‌فرض با نصب پایتون همراه است. تنها کاری که باید انجام دهید، وارد کردن (import) آن در ابتدای کد خود است:

import json

نکته: ماژول `json` از نظر عملکرد بسیار بهینه است، اما اگر با حجم بسیار زیادی از داده‌ها سروکار دارید و نیاز به سرعت حداکثری دارید، ممکن است کتابخانه‌های جانبی مثل `ujson` یا `orjson` گزینه‌های سریع‌تری باشند. با این حال، برای اکثر کاربردها، ماژول داخلی پایتون کاملاً کافی و قابل اعتماد است.

تبدیل JSON به داده‌های پایتون (Deserialization)

Deserialization فرآیند تبدیل یک رشته یا فایل JSON به معادل آن در ساختارهای داده‌ای پایتون (معمولاً دیکشنری‌ها و لیست‌ها) است.

خواندن JSON از یک رشته با `json.loads()`

تابع `json.loads()` (کوتاه شده “load string”) برای تبدیل یک رشته JSON به یک آبجکت پایتون استفاده می‌شود. اگر رشته JSON یک آبجکت JSON باشد، به یک دیکشنری پایتون تبدیل می‌شود؛ اگر یک آرایه JSON باشد، به یک لیست پایتون تبدیل می‌شود.

import json

# یک رشته JSON
json_string = '''
{
    "name": "علی احمدی",
    "age": 30,
    "city": "تهران",
    "is_student": false,
    "grades": [18, 19, 20]
}
'''

# تبدیل رشته JSON به دیکشنری پایتون
data = json.loads(json_string)

# چاپ نوع و محتوای داده
print(type(data))
print(data)

# دسترسی به عناصر دیکشنری
print(f"نام: {data['name']}")
print(f"شهر: {data['city']}")
print(f"اولین نمره: {data['grades'][0]}")

# مثال با یک لیست JSON
json_list_string = '[{"id": 1, "item": "شیر"}, {"id": 2, "item": "نان"}]'
items = json.loads(json_list_string)
print(type(items))
print(items[0]['item'])

خروجی کد بالا:

<class 'dict'>
{'name': 'علی احمدی', 'age': 30, 'city': 'تهران', 'is_student': False, 'grades': [18, 19, 20]}
نام: علی احمدی
شهر: تهران
اولین نمره: 18
<class 'list'>
شیر

خواندن JSON از یک فایل با `json.load()`

تابع `json.load()` (کوتاه شده “load file”) مستقیماً از یک فایل JSON می‌خواند و محتوای آن را به یک آبجکت پایتون تبدیل می‌کند. این تابع یک شیء فایل (file object) را به‌عنوان ورودی می‌پذیرد.

فرض کنید فایلی به نام `data.json` داریم با محتوای زیر:

# محتوای فایل data.json
{
    "products": [
        {"id": 1, "name": "لپ‌تاپ", "price": 15000000},
        {"id": 2, "name": "ماوس", "price": 500000}
    ],
    "company": "تکنولوژی نوین"
}
import json

# ابتدا یک فایل JSON نمونه ایجاد می‌کنیم
sample_data = {
    "products": [
        {"id": 1, "name": "لپ‌تاپ", "price": 15000000},
        {"id": 2, "name": "ماوس", "price": 500000}
    ],
    "company": "تکنولوژی نوین"
}
with open('data.json', 'w', encoding='utf-8') as f:
    json.dump(sample_data, f, ensure_ascii=False, indent=4)

# خواندن از فایل JSON
try:
    with open('data.json', 'r', encoding='utf-8') as f:
        file_data = json.load(f)
    print(f"داده‌های خوانده شده از فایل: {file_data}")
    print(f"نام شرکت: {file_data['company']}")
    print(f"اولین محصول: {file_data['products'][0]['name']}")
except FileNotFoundError:
    print("خطا: فایل data.json یافت نشد.")
except json.JSONDecodeError:
    print("خطا: فرمت فایل JSON نامعتبر است.")

خروجی کد بالا:

داده‌های خوانده شده از فایل: {'products': [{'id': 1, 'name': 'لپ‌تاپ', 'price': 15000000}, {'id': 2, 'name': 'ماوس', 'price': 500000}], 'company': 'تکنولوژی نوین'}
نام شرکت: تکنولوژی نوین
اولین محصول: لپ‌تاپ

تبدیل داده‌های پایتون به JSON (Serialization)

Serialization فرآیند تبدیل ساختارهای داده‌ای پایتون (دیکشنری‌ها، لیست‌ها و غیره) به یک رشته یا فایل با فرمت JSON است.

تبدیل به رشته JSON با `json.dumps()`

تابع `json.dumps()` (کوتاه شده “dump string”) یک آبجکت پایتون را به یک رشته JSON تبدیل می‌کند. این تابع بسیار کاربردی است، به‌ویژه زمانی که می‌خواهید داده‌ها را برای ارسال از طریق شبکه (مثل پاسخ API) آماده کنید یا آن‌ها را در لاگ‌ها چاپ نمایید.

import json

# یک دیکشنری پایتون
python_dict = {
    "name": "سارا محمدی",
    "age": 25,
    "emails": ["sara.m@example.com", "sm.personal@mail.com"],
    "is_active": True,
    "address": None
}

# تبدیل دیکشنری به رشته JSON
json_output = json.dumps(python_dict)
print(type(json_output))
print(json_output)

# برای خوانایی بیشتر، می‌توان از پارامتر 'indent' استفاده کرد
pretty_json_output = json.dumps(python_dict, indent=4, ensure_ascii=False) # ensure_ascii=False برای نمایش صحیح حروف فارسی
print("nخروجی JSON با فرمت زیبا:")
print(pretty_json_output)

خروجی کد بالا:

<class 'str'>
{"name": "سارا محمدی", "age": 25, "emails": ["sara.m@example.com", "sm.personal@mail.com"], "is_active": true, "address": null}

خروجی JSON با فرمت زیبا:
{
    "name": "سارا محمدی",
    "age": 25,
    "emails": [
        "sara.m@example.com",
        "sm.personal@mail.com"
    ],
    "is_active": true,
    "address": null
}

نوشتن JSON در یک فایل با `json.dump()`

تابع `json.dump()` (کوتاه شده “dump file”) مستقیماً یک آبجکت پایتون را به یک فایل JSON می‌نویسد. این تابع یک آبجکت پایتون و یک شیء فایل (file object) را به‌عنوان ورودی می‌پذیرد.

import json

# یک لیست پایتون از دیکشنری‌ها
users = [
    {"id": 101, "username": "رضا کریمی", "status": "فعال"},
    {"id": 102, "username": "مریم حسینی", "status": "غیرفعال", "last_login": "2023-10-26"}
]

# نوشتن لیست در فایل users.json
file_path = 'users.json'
try:
    with open(file_path, 'w', encoding='utf-8') as f:
        json.dump(users, f, indent=4, ensure_ascii=False)
    print(f"داده‌ها با موفقیت در فایل '{file_path}' ذخیره شدند.")
except IOError as e:
    print(f"خطا در نوشتن فایل: {e}")

# بررسی محتوای فایل (اختیاری)
# با باز کردن فایل 'users.json' می‌توانید محتوای آن را ببینید.
# این کد برای نمایش محتوا در خروجی کنسول است:
with open(file_path, 'r', encoding='utf-8') as f:
    print("nمحتوای فایل users.json:")
    print(f.read())

خروجی کد بالا:

داده‌ها با موفقیت در فایل 'users.json' ذخیره شدند.

محتوای فایل users.json:
[
    {
        "id": 101,
        "username": "رضا کریمی",
        "status": "فعال"
    },
    {
        "id": 102,
        "username": "مریم حسینی",
        "status": "غیرفعال",
        "last_login": "2023-10-26"
    }
]

کار با ساختارهای پیچیده JSON

JSON می‌تواند ساختارهای داده‌ای تودرتو و پیچیده‌ای داشته باشد. پایتون با انعطاف‌پذیری خود، کار با این ساختارها را بسیار ساده می‌کند.

دیکشنری‌های تودرتو

یک آبجکت JSON می‌تواند شامل آبجکت‌های JSON دیگری باشد. در پایتون، این‌ها به دیکشنری‌های تودرتو (nested dictionaries) تبدیل می‌شوند.

import json

complex_json_string = '''
{
    "employee": {
        "id": "E001",
        "personal_info": {
            "first_name": "حسن",
            "last_name": "باقری",
            "age": 45
        },
        "contact": {
            "email": "h.bagheri@company.com",
            "phone": ["123-456-7890", "987-654-3210"]
        },
        "skills": ["Python", "SQL", "DevOps"]
    }
}
'''

data = json.loads(complex_json_string)

# دسترسی به عناصر تودرتو
employee_info = data['employee']
personal_info = employee_info['personal_info']
contact_info = employee_info['contact']

print(f"نام کامل: {personal_info['first_name']} {personal_info['last_name']}")
print(f"ایمیل: {contact_info['email']}")
print(f"مهارت اول: {employee_info['skills'][0]}")
print(f"شماره تماس دوم: {contact_info['phone'][1]}")

خروجی کد بالا:

نام کامل: حسن باقری
ایمیل: h.bagheri@company.com
مهارت اول: Python
شماره تماس دوم: 987-654-3210

لیست دیکشنری‌ها و دیکشنری لیست‌ها

ساختارهای رایج دیگر شامل لیست‌هایی از دیکشنری‌ها یا دیکشنری‌هایی که مقادیرشان لیست هستند، می‌باشند.

import json

# لیست دیکشنری‌ها
products_json = '''
[
    {"id": 1, "name": "تلویزیون", "category": "الکترونیک", "price": 25000000},
    {"id": 2, "name": "کتاب پایتون", "category": "کتاب", "price": 500000},
    {"id": 3, "name": "میز کامپیوتر", "category": "مبلمان", "price": 1200000}
]
'''
products = json.loads(products_json)

# پیمایش لیست محصولات
for product in products:
    print(f"شناسه: {product['id']}, نام: {product['name']}, قیمت: {product['price']}")

# دیکشنری با لیست‌ها به عنوان مقدار
categories_json = '''
{
    "electronics": ["لپ‌تاپ", "موبایل", "هدفون"],
    "books": ["رمان", "علمی", "برنامه‌نویسی"]
}
'''
categories = json.loads(categories_json)

# دسترسی به آیتم‌های لیست
print(f"nمحصولات الکترونیک: {categories['electronics']}")
print(f"کتاب‌های برنامه‌نویسی: {categories['books'][2]}")

خروجی کد بالا:

شناسه: 1, نام: تلویزیون, قیمت: 25000000
شناسه: 2, نام: کتاب پایتون, قیمت: 500000
شناسه: 3, نام: میز کامپیوتر, قیمت: 1200000

محصولات الکترونیک: ['لپ‌تاپ', 'موبایل', 'هدفون']
کتاب‌های برنامه‌نویسی: برنامه‌نویسی

مدیریت خطاها در پردازش JSON

هنگام کار با JSON، به‌ویژه داده‌هایی که از منابع خارجی می‌آیند، ممکن است با فرمت‌های نامعتبر یا داده‌های غیرمنتظره روبرو شوید. پایتون با مدیریت استثنا (exception handling) این امکان را فراهم می‌کند که به‌صورت گریس‌فول (graceful) با این خطاها برخورد کنید.

`json.JSONDecodeError`

این خطا زمانی رخ می‌دهد که رشته یا فایل JSON ارائه‌شده از نظر گرامری (syntax) اشتباه باشد و `json.loads()` یا `json.load()` نتوانند آن را تجزیه کنند. استفاده از بلوک `try-except` برای این مورد ضروری است.

import json

malformed_json_string = '''
{
    "name": "محسن",
    "age": 40,
    "city": "اصفهان", # اینجا ویرگول اضافه است که باعث خطا می‌شود
}
'''

try:
    data = json.loads(malformed_json_string)
    print("JSON با موفقیت تجزیه شد:", data)
except json.JSONDecodeError as e:
    print(f"خطا در تجزیه JSON: {e}")
    print(f"موقعیت خطا: در خط {e.lineno}, ستون {e.colno}")

# مثال دیگر: JSON کاملا نامعتبر
invalid_json = "این یک رشته JSON نیست"
try:
    data = json.loads(invalid_json)
    print("JSON با موفقیت تجزیه شد:", data)
except json.JSONDecodeError as e:
    print(f"nخطا در تجزیه JSON کاملاً نامعتبر: {e}")

خروجی کد بالا:

خطا در تجزیه JSON: Expecting property name or '}' at line 5 column 5 (char 55)
موقعیت خطا: در خط 5, ستون 5

خطا در تجزیه JSON کاملاً نامعتبر: Expecting value: line 1 column 1 (char 0)

تنظیمات پیشرفته و بهینه‌سازی

ماژول `json` پایتون گزینه‌های انعطاف‌پذیری برای کنترل نحوه سریالایز و دی‌سریالایز کردن داده‌ها فراهم می‌کند.

زیباسازی خروجی با `indent`

پارامتر `indent` در توابع `json.dumps()` و `json.dump()` به شما اجازه می‌دهد تا خروجی JSON را با تورفتگی (indentation) مناسب فرمت کنید تا خواندن آن برای انسان آسان‌تر شود. مقدار `indent` تعداد فاصله‌های (space) تورفتگی را مشخص می‌کند.

import json

data = {
    "item": "مانیتور",
    "details": {
        "brand": "سامسونگ",
        "size": 27,
        "features": ["4K", "HDR", "USB-C"]
    }
}

# بدون تورفتگی (پیش‌فرض)
compact_json = json.dumps(data, ensure_ascii=False)
print("JSON فشرده:")
print(compact_json)

# با تورفتگی 4 فاصله
pretty_json = json.dumps(data, indent=4, ensure_ascii=False)
print("nJSON زیبا (indent=4):")
print(pretty_json)

# با تورفتگی 2 فاصله
two_space_json = json.dumps(data, indent=2, ensure_ascii=False)
print("nJSON زیبا (indent=2):")
print(two_space_json)

خروجی کد بالا:

JSON فشرده:
{"item": "مانیتور", "details": {"brand": "سامسونگ", "size": 27, "features": ["4K", "HDR", "USB-C"]}}

JSON زیبا (indent=4):
{
    "item": "مانیتور",
    "details": {
        "brand": "سامسونگ",
        "size": 27,
        "features": [
            "4K",
            "HDR",
            "USB-C"
        ]
    }
}

JSON زیبا (indent=2):
{
  "item": "مانیتور",
  "details": {
    "brand": "سامسونگ",
    "size": 27,
    "features": [
      "4K",
      "HDR",
      "USB-C"
    ]
  }
}

ترتیب کلیدها با `sort_keys`

پارامتر `sort_keys=True` باعث می‌شود کلیدهای دیکشنری در خروجی JSON به‌صورت الفبایی مرتب شوند. این ویژگی برای تولید خروجی‌های سازگار (canonical) و قابل مقایسه مفید است.

import json

data = {
    "c_key": "مقدار C",
    "a_key": "مقدار A",
    "b_key": "مقدار B"
}

# بدون ترتیب کلیدها (ترتیب پیش‌فرض ممکن است متفاوت باشد)
no_sort = json.dumps(data, indent=2, ensure_ascii=False)
print("بدون ترتیب:")
print(no_sort)

# با ترتیب کلیدها
sorted_json = json.dumps(data, indent=2, sort_keys=True, ensure_ascii=False)
print("nبا ترتیب (الفبایی):")
print(sorted_json)

خروجی کد بالا:

بدون ترتیب:
{
  "c_key": "مقدار C",
  "a_key": "مقدار A",
  "b_key": "مقدار B"
}

با ترتیب (الفبایی):
{
  "a_key": "مقدار A",
  "b_key": "مقدار B",
  "c_key": "مقدار C"
}

سفارشی‌سازی سریالایزرها و دی‌سریالایزرها

اگر نیاز دارید آبجکت‌های پایتون خاصی (مانند `datetime` یا کلاس‌های سفارشی) را به JSON تبدیل کنید که به‌طور پیش‌فرض پشتیبانی نمی‌شوند، می‌توانید از کلاس `JSONEncoder` و `JSONDecoder` سفارشی استفاده کنید. این یک قابلیت پیشرفته است و زمانی مفید است که شما با انواع داده‌ی غیر استاندارد سروکار دارید.

import json
import datetime

# یک کلاس سفارشی برای کدگذاری datetime
class DateTimeEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime.datetime):
            # تبدیل به فرمت ISO 8601
            return obj.isoformat()
        # بقیه انواع را به متد پیش‌فرض ارسال کن
        return json.JSONEncoder.default(self, obj)

data_with_datetime = {
    "event_name": "جلسه پروژه",
    "event_time": datetime.datetime.now(),
    "location": "دفتر مرکزی"
}

# استفاده از کدگذار سفارشی
json_output = json.dumps(data_with_datetime, indent=4, cls=DateTimeEncoder, ensure_ascii=False)
print("JSON با تاریخ و زمان سفارشی:")
print(json_output)

# برای دیکد کردن سفارشی (مثل تبدیل رشته تاریخ به شی datetime)
# نیاز به یک متد hook برای json.loads() داریم.
# این یک مثال ساده است:
def datetime_decoder_hook(dct):
    for k, v in dct.items():
        if isinstance(v, str) and "T" in v and "-" in v and ":" in v: # یک شرط ساده برای تشخیص تاریخ ISO
            try:
                dct[k] = datetime.datetime.fromisoformat(v)
            except ValueError:
                pass
    return dct

decoded_data = json.loads(json_output, object_hook=datetime_decoder_hook)
print("nداده‌های دیکد شده با تبدیل تاریخ:")
print(decoded_data)
print(f"نوع event_time پس از دیکد: {type(decoded_data['event_time'])}")

خروجی کد بالا:

JSON با تاریخ و زمان سفارشی:
{
    "event_name": "جلسه پروژه",
    "event_time": "2023-10-26T10:30:00.123456",
    "location": "دفتر مرکزی"
}

داده‌های دیکد شده با تبدیل تاریخ:
{'event_name': 'جلسه پروژه', 'event_time': 2023-10-26 10:30:00.123456, 'location': 'دفتر مرکزی'}
نوع event_time پس از دیکد: <class 'datetime.datetime'>

(توجه: زمان دقیق در خروجی بسته به زمان اجرای کد متفاوت خواهد بود.)

کاربردهای عملی JSON در پایتون

قابلیت پایتون در کار با JSON، آن را به ابزاری قدرتمند برای سناریوهای مختلف تبدیل کرده است. در اینجا به دو مثال رایج اشاره می‌کنیم.

خواندن پاسخ API

بسیاری از APIهای وب، داده‌ها را با فرمت JSON برمی‌گردانند. پایتون با کتابخانه‌ی `requests` می‌تواند به‌راحتی این پاسخ‌ها را دریافت و پردازش کند.

نکته: برای اجرای کد زیر، باید کتابخانه `requests` را نصب کنید: pip install requests

import requests
import json

# یک API عمومی برای نمونه (مثلاً JSONPlaceholder برای پست‌ها)
api_url = "https://jsonplaceholder.typicode.com/posts/1"

try:
    response = requests.get(api_url)
    response.raise_for_status() # اگر کد وضعیت HTTP خطا باشد (مثل 4xx یا 5xx)، خطا ایجاد می‌کند.

    # requests خودش متد .json() را برای تجزیه پاسخ JSON دارد
    post_data = response.json()

    print("پاسخ API:")
    print(json.dumps(post_data, indent=4)) # برای نمایش زیبا

    print(f"nعنوان پست: {post_data['title']}")
    print(f"بدنه پست: {post_data['body']}")

except requests.exceptions.HTTPError as errh:
    print(f"خطای HTTP: {errh}")
except requests.exceptions.ConnectionError as errc:
    print(f"خطای اتصال: {errc}")
except requests.exceptions.Timeout as errt:
    print(f"خطای زمان‌بندی: {errt}")
except requests.exceptions.RequestException as err:
    print(f"خطای کلی: {err}")
except json.JSONDecodeError:
    print("خطا: پاسخ دریافتی JSON معتبر نیست.")

خروجی کد بالا (ممکن است بسته به زمان اجرای درخواست کمی متفاوت باشد):

پاسخ API:
{
    "userId": 1,
    "id": 1,
    "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
    "body": "quia et suscipitnsuscipit recusandae consequuntur expedita et cumnreprehenderit molestiae ut ut quas totamnnostrum rerum est autem sunt rem eveniet architecto"
}

عنوان پست: sunt aut facere repellat provident occaecati excepturi optio reprehenderit
بدنه پست: quia et suscipit
suscipit recusandae consequuntur expedita et cum
reprehenderit molestiae ut ut quas totam
nostrum rerum est autem sunt rem eveniet architecto

ذخیره‌سازی و بارگذاری تنظیمات

JSON یک فرمت عالی برای ذخیره‌سازی فایل‌های پیکربندی (configuration files) است. این کار به شما امکان می‌دهد تنظیمات برنامه را به‌راحتی تغییر دهید بدون اینکه نیاز به تغییر کد داشته باشید.

import json
import os

config_file = 'app_config.json'

# تنظیمات پیش‌فرض
default_config = {
    "database": {
        "host": "localhost",
        "port": 5432,
        "user": "admin"
    },
    "logging": {
        "level": "INFO",
        "file": "app.log"
    },
    "version": "1.0.0"
}

def load_config():
    """بارگذاری تنظیمات از فایل JSON"""
    if os.path.exists(config_file):
        with open(config_file, 'r', encoding='utf-8') as f:
            return json.load(f)
    return default_config # اگر فایل وجود نداشت، تنظیمات پیش‌فرض را برگردان

def save_config(config_data):
    """ذخیره تنظیمات در فایل JSON"""
    with open(config_file, 'w', encoding='utf-8') as f:
        json.dump(config_data, f, indent=4, ensure_ascii=False)

# مثال استفاده
current_config = load_config()
print("تنظیمات فعلی:", current_config)

# تغییر یک تنظیم
current_config['logging']['level'] = 'DEBUG'
current_config['version'] = '1.0.1'

# اضافه کردن یک تنظیم جدید
current_config['server_timeout_seconds'] = 30

save_config(current_config)
print("nتنظیمات پس از تغییر و ذخیره:")
print(load_config())

# پاک کردن فایل تنظیمات برای تست‌های بعدی (اختیاری)
# os.remove(config_file)

خروجی کد بالا:

تنظیمات فعلی: {'database': {'host': 'localhost', 'port': 5432, 'user': 'admin'}, 'logging': {'level': 'INFO', 'file': 'app.log'}, 'version': '1.0.0'}

تنظیمات پس از تغییر و ذخیره:
{'database': {'host': 'localhost', 'port': 5432, 'user': 'admin'}, 'logging': {'level': 'DEBUG', 'file': 'app.log'}, 'version': '1.0.1', 'server_timeout_seconds': 30}

مقایسه توابع اصلی `json` در پایتون

در جدول زیر، توابع اصلی ماژول `json` را برای درک بهتر تفاوت‌های آن‌ها مقایسه کرده‌ایم.

تابع ورودی خروجی هدف مثال کاربردی
`json.loads()` رشته JSON (`str`) آبجکت پایتون (dict/list) Deserialization (خواندن JSON از یک رشته) پردازش پاسخ‌های JSON از API
`json.load()` شیء فایل (file object) آبجکت پایتون (dict/list) Deserialization (خواندن JSON از یک فایل) بارگذاری تنظیمات یا داده‌ها از فایل
`json.dumps()` آبجکت پایتون (dict/list) رشته JSON (`str`) Serialization (تبدیل به رشته JSON) آماده‌سازی داده‌ها برای ارسال به API
`json.dump()` آبجکت پایتون (dict/list) و شیء فایل نوشتن در فایل Serialization (نوشتن JSON در یک فایل) ذخیره‌سازی داده‌ها یا لاگ‌ها در فایل

عیب‌یابی سریع (Troubleshooting)

  • `json.JSONDecodeError` هنگام `loads()` یا `load()`:

    این شایع‌ترین خطا است. به این معنی است که رشته JSON شما از نظر گرامری (syntax) نادرست است. مطمئن شوید که:

    • همه نام‌های کلید (key) در کوتیشن دابل (") هستند.
    • رشته‌ها با کوتیشن دابل (") احاطه شده‌اند (نه سینگل ').
    • ویرگول‌ها (,) به‌درستی بین جفت‌های کلید-مقدار و عناصر لیست قرار گرفته‌اند و ویرگول اضافی در انتهای آبجکت/لیست وجود ندارد.
    • پرانتزهای باز و بسته ({} و []) به‌درستی با هم تطابق دارند.
    • اگر از فایل می‌خوانید، مطمئن شوید فایل خراب نیست یا خالی نمی‌باشد.

    راه حل: از یک JSON Validator آنلاین استفاده کنید تا مطمئن شوید رشته JSON شما معتبر است. پیغام خطای پایتون معمولاً شماره خط و ستون را مشخص می‌کند که در پیدا کردن مشکل کمک شایانی می‌کند.

  • `TypeError: Object of type X is not JSON serializable` هنگام `dumps()` یا `dump()`:

    این خطا زمانی رخ می‌دهد که سعی دارید یک آبجکت پایتون (مانند `datetime`، `set` یا یک کلاس سفارشی) را سریالایز کنید که ماژول `json` به‌طور پیش‌فرض نحوه تبدیل آن را نمی‌داند.

    راه حل: باید یک `JSONEncoder` سفارشی بنویسید (همانطور که در بخش “سفارشی‌سازی سریالایزرها” توضیح داده شد) تا نحوه تبدیل آن نوع داده خاص را به JSON مشخص کنید. همچنین، می‌توانید آبجکت را به یک نوع داده استاندارد JSON (مثل رشته برای تاریخ‌ها یا لیست برای `set`ها) تبدیل کنید قبل از سریالایز کردن.

  • مشکل در نمایش حروف فارسی یا غیر ASCII:

    اگر حروف فارسی یا کاراکترهای خاص به‌صورت `uXXXX` در خروجی JSON نمایش داده می‌شوند، یا اگر از فایل می‌خوانید/می‌نویسید و با کاراکترهای نامفهوم مواجه می‌شوید.

    راه حل: هنگام استفاده از `json.dumps()` یا `json.dump()`، پارامتر `ensure_ascii=False` را اضافه کنید. همچنین هنگام باز کردن فایل‌ها برای خواندن یا نوشتن، حتماً `encoding=’utf-8’` را مشخص کنید.

  • عدم یافتن کلید در دیکشنری پایتون پس از `json.loads()`:

    اگر مطمئن هستید که کلید در JSON اصلی وجود دارد، اما پس از تبدیل به دیکشنری پایتون با `KeyError` مواجه می‌شوید.

    راه حل: کلیدها در JSON و پایتون به حروف بزرگ و کوچک حساس هستند (case-sensitive). دوبار بررسی کنید که نام کلید را دقیقاً همانطور که در JSON هست، استفاده می‌کنید. می‌توانید با `print(data.keys())` تمام کلیدهای موجود را ببینید. همچنین، از متد `data.get(‘key_name’, default_value)` برای دسترسی ایمن‌تر به کلیدها استفاده کنید تا در صورت عدم وجود کلید، به جای خطا، یک مقدار پیش‌فرض دریافت کنید.

سوالات متداول (FAQ)

JSON چیست و چرا از آن استفاده می‌کنیم؟

JSON (JavaScript Object Notation) یک فرمت متنی سبک برای تبادل داده است که هم برای انسان‌ها قابل خواندن و هم برای ماشین‌ها قابل تجزیه است. ما از آن برای انتقال داده بین سرور و کلاینت (در APIها)، ذخیره فایل‌های پیکربندی و به طور کلی هر جایی که نیاز به نمایش ساختاریافته داده‌ها داریم، استفاده می‌کنیم.

تفاوت اصلی بین `json.load()` و `json.loads()` چیست؟

`json.loads()` (load string) یک رشته JSON را به‌عنوان ورودی می‌گیرد و آن را به یک آبجکت پایتون تبدیل می‌کند. در مقابل، `json.load()` (load file) یک شیء فایل (file object) را به‌عنوان ورودی می‌گیرد و محتوای JSON آن فایل را به یک آبجکت پایتون تبدیل می‌کند.

چگونه می‌توانم خروجی JSON را خواناتر کنم؟

با استفاده از پارامتر `indent` در توابع `json.dumps()` یا `json.dump()`. مثلاً `json.dumps(data, indent=4)` خروجی JSON را با تورفتگی چهار فاصله زیبا و خوانا می‌کند.

چرا حروف فارسی در JSON به صورت `uXXXX` نمایش داده می‌شوند؟

این رفتار پیش‌فرض ماژول `json` پایتون است تا از سازگاری با سیستم‌های قدیمی ASCII اطمینان حاصل کند. برای نمایش صحیح حروف فارسی، باید هنگام سریالایز کردن از `ensure_ascii=False` استفاده کنید: `json.dumps(data, ensure_ascii=False)`.

چگونه با خطاهای فرمت JSON نامعتبر برخورد کنم؟

باید از بلوک `try-except` برای مدیریت `json.JSONDecodeError` استفاده کنید. این خطا زمانی رخ می‌دهد که رشته JSON از نظر گرامری اشتباه باشد. به این صورت می‌توانید برنامه خود را از کرش کردن نجات دهید و خطا را به‌درستی گزارش کنید.

نتیجه‌گیری

در این مقاله، ما به صورت جامع و کاربردی به بررسی کدهای آماده برای کار با JSON در پایتون پرداختیم. از مفاهیم پایه‌ای تبدیل داده‌ها بین فرمت JSON و ساختارهای پایتون گرفته تا مدیریت فایل‌ها، ساختارهای پیچیده، و راهکارهای عیب‌یابی، تمام جنبه‌های ضروری را پوشش دادیم. ماژول `json` پایتون با سادگی و قدرت خود، ابزاری بی‌نظیر برای هر توسعه‌دهنده‌ای است که با داده‌های ساختاریافته سروکار دارد. با به‌کارگیری این کدها و اصول، شما می‌توانید به‌راحتی داده‌های JSON را در پروژه‌های خود مدیریت کرده و از قدرت پایتون در این زمینه نهایت استفاده را ببرید. یادگیری این مهارت به شما کمک می‌کند تا به راحتی با APIها تعامل داشته باشید و اطلاعات را به شکلی کارآمد ذخیره و بازیابی کنید. اکنون، با دانشی که کسب کردید، می‌توانید با اطمینان کامل به دنیای داده‌ها قدم بگذارید و پروژه‌های موفقی را رقم بزنید.

Table of Contents

آخرین نوشته‌ها