معالجة بيانات JSON

JSON (JavaScript Object Notation) هو تنسيق تبادل البيانات الأكثر شيوعاً على الويب. تقريباً جميع واجهات برمجة تطبيقات الويب تُرجع بيانات JSON. وحدة json في بايثون تجعل التحويل بين كائنات بايثون وسلاسل JSON سهلاً.


1. كائنات بايثون <-> سلاسل JSON

مثال: التسلسل إلى سلسلة JSON

PYTHON
import json

# قاموس بايثون -> سلسلة JSON (تسلسل)
data = {
    "name": "Zhang San",
    "age": 25,
    "is_student": False,
    "scores": [85, 92, 78],
    "address": None
}

json_str = json.dumps(data, ensure_ascii=False, indent=2)
print(json_str)
▶ جرّب الكود

المخرجات:

JSON
{
  "name": "Zhang San",
  "age": 25,
  "is_student": false,
  "scores": [85, 92, 78],
  "address": null
}
💡 ensure_ascii=False مهم: بدون هذا المعامل، يتم هروب الأحرف غير ASCII إلى رموز Unicode. استخدمه للحفاظ على الأحرف الأصلية. indent=2 يُنسق الإخراج لسهولة القراءة. في الإنتاج، استخدم indent=None لضغطه في سطر واحد، لتوفير عرض النطاق الترددي.


2. سلسلة JSON -> كائنات بايثون (إلغاء التسلسل)

مثال: إلغاء تسلسل سلسلة JSON

PYTHON
import json

json_str = '{"name": "Zhang San", "age": 25, "is_student": false, "scores": [85, 92, 78]}'

data = json.loads(json_str)
print(data)                             # {'name': 'Zhang San', 'age': 25, ...}
print(type(data))                       # <class 'dict'>
print(data["name"])                     # Zhang San
print(data["scores"][0])                # 85
▶ جرّب الكود

تعيين نوع JSON إلى نوع بايثون

JSON بايثون
string str
number int / float
boolean bool
null None
array list
object dict

3. إدخال/إخراج ملفات JSON

مثال: قراءة وكتابة ملفات JSON

PYTHON
import json

# اكتب إلى ملف JSON
data = {
    "students": [
        {"name": "Zhang San", "age": 20, "score": 85},
        {"name": "Li Si", "age": 21, "score": 92},
        {"name": "Wang Wu", "age": 19, "score": 78}
    ]
}

with open("students.json", "w", encoding="utf-8") as f:
    json.dump(data, f, ensure_ascii=False, indent=2)

# اقرأ ملف JSON
with open("students.json", "r", encoding="utf-8") as f:
    loaded = json.load(f)

print(f"Number of students: {len(loaded['students'])}")
for s in loaded["students"]:
    print(f"  {s['name']}: {s['score']}")
▶ جرّب الكود

مثال: استمرارية البيانات (الصعوبة ⭐⭐)

PYTHON
import json
import os

DATA_FILE = "notes.json"

def load_notes():
    """حمّل الملاحظات من ملف JSON"""
    if not os.path.exists(DATA_FILE):
        return []
    with open(DATA_FILE, "r", encoding="utf-8") as f:
        return json.load(f)

def save_notes(notes):
    """احفظ الملاحظات إلى ملف JSON"""
    with open(DATA_FILE, "w", encoding="utf-8") as f:
        json.dump(notes, f, ensure_ascii=False, indent=2)

def add_note(title, content):
    """أضف ملاحظة"""
    notes = load_notes()
    notes.append({"title": title, "content": content})
    save_notes(notes)
    print(f"Note added: {title}")

def list_notes():
    """اعرض جميع الملاحظات"""
    notes = load_notes()
    if not notes:
        print("No notes yet")
        return
    for i, note in enumerate(notes, 1):
        print(f"{i}. {note['title']}")

add_note("Learning Python", "Learned the JSON module today")
add_note("Shopping List", "Buy milk, bread, eggs")
list_notes()
▶ جرّب الكود

4. التعامل مع أنواع البيانات المعقدة

افتراضياً، وحدة json تدعم فقط الأنواع الأساسية. الكائنات المخصصة تحتاج تحويلاً يدوياً:

مثال: تسلسل مخصص

PYTHON
import json
from datetime import datetime

def custom_serializer(obj):
    """تسلسل مخصص — يتعامل مع أنواع مثل datetime"""
    if isinstance(obj, datetime):
        return obj.strftime("%Y-%m-%d %H:%M:%S")
    raise TypeError(f"Cannot serialize {type(obj)}")

data = {
    "name": "Zhang San",
    "created_at": datetime.now(),
    "active": True
}

json_str = json.dumps(data, default=custom_serializer, ensure_ascii=False, indent=2)
print(json_str)
▶ جرّب الكود

حالات الاستخدام الشائعة


❓ أسئلة شائعة

س ما الفرق بين json.dumps() و json.dump()؟
ج dumps() تُرجع سلسلة JSON (s للـ string)؛ dump() تكتب مباشرة إلى كائن ملف. وبالمثل، loads() تحلل من سلسلة؛ load() تقرأ من كائن ملف. اللاحقة 's' تشير إلى سلسلة. س:ما مزايا JSON على CSV؟ ج:JSON يدعم الهياكل المتداخلة (قواميس داخل قوائم، قوائم داخل قواميس)، بينما CSV يمكنه فقط تمثيل جداول مسطحة. JSON يحافظ على أنواع البيانات تلقائياً (أرقام، قيم منطقية، null)، بينما كل قيم CSV هي سلاسل نصية. JSON أكثر قابلية للقراءة. الجانب السلبي هو أن ملفات JSON عادة أكبر من CSV. س:ماذا يحدث إذا لم يتم تعيين ensure_ascii=False؟ ج:سيتم هروب الأحرف العربية/الصينية إلى تنسيق \uXXXX. وظيفة البرنامج غير متأثرة — json.loads() سيعيدها تلقائياً. لكن لسهولة القراءة البشرية، المحتوى المهروب غير قابل للقراءة تماماً. أضف ensure_ascii=False عندما تحتاج لعرض ملفات JSON يدوياً.

📖 ملخص

  • json.dumps() بايثون -> سلسلة JSON؛ json.loads() سلسلة JSON -> بايثون
  • json.dump() بايثون -> ملف JSON؛ json.load() ملف JSON -> بايثون
  • ensure_ascii=False يحافظ على الأحرف غير ASCII؛ indent=2 يُنسق الإخراج
  • تعيين أنواع JSON: object->dict, array->list, number->int/float, null->None
  • الأنواع المخصصة تحتاج دالة تسلسل default

📝 تمارين

  1. أساسي (الصعوبة ⭐): أنشئ قاموساً يحتوي على اسمك وعمرك وثلاث هوايات (قائمة). استخدم json.dumps() لإخراج سلسلة JSON منسقة (احفظ الأحرف، مسافة بادئة 2).

  2. متوسط (الصعوبة ⭐⭐): اكتب دالتين: save_contacts(contacts) و load_contacts(). احفظ قائمة جهات اتصال (قائمة قواميس) إلى contacts.json وتحميل تلقائي عند بدء البرنامج. كل جهة اتصال لها اسم وهاتف وبريد إلكتروني.

  3. تحدي (الصعوبة ⭐⭐⭐): نفذ "مُصدّر بيانات بسيط" باستخدام JSON. بالنظر إلى قائمة درجات الطلاب students = [{"name": "Zhang San", "scores": {"Chinese": 85, "Math": 92}}]، أخرج كـ: 1) ملف JSON منسق؛ 2) سلسلة JSON مضغوطة (بدون مسافة بادئة)؛ 3) سلسلة JSON بمفاتيح مرتبة (sort_keys=True).

100%