تخطَّ إلى المحتوى

التعامل مع JSON في Python

الدرس 23 من 25 · Python

في درس الملفات حفظت نصوصاً وأرقاماً بسيطة. لكن بيانات البرامج الحقيقية أعقد: قائمة طلاب، ولكل طالب اسم وعمر وهوايات. كيف تحفظ قاموساً أو قائمة قواميس في ملف؟ الحل هو JSON، أشهر صيغة لتبادل البيانات في العالم. ستجدها في ملفات الإعدادات، وفي تطبيقات الموبايل، وفي كل موقع يجلب بياناته من الإنترنت.

JSON طريقة متفق عليها لكتابة البيانات كنص، بحيث يفهمها أي برنامج بأي لغة. تخيّلها مثل لغة مشتركة بين مسافرين من بلاد مختلفة: برنامج Python يكتب البيانات بها، وتطبيق مكتوب بلغة أخرى يقرؤها دون مشكلة.

وشكلها سيبدو لك مألوفاً جداً، فهي تشبه قواميس Python وقوائمها:

{
"name": "سارة",
"age": 15,
"passed": true,
"hobbies": ["القراءة", "الرسم"],
"phone": null
}

هناك فروق قليلة عن Python يجب أن تعرفها:

في Python في JSON
قاموس dict كائن بين { }
قائمة list أو صف tuple مصفوفة بين [ ]
نص بعلامات مفردة أو مزدوجة نص بعلامات مزدوجة فقط
True و False true و false
None null

والخبر الجيد أنك لا تحتاج أن تحفظ هذا الجدول، فالوحدة json الجاهزة في Python تقوم بالتحويل عنك.

الدالة json.dumps تحوّل قيمة Python إلى نص بصيغة JSON:

import json
student = {"name": "سارة", "age": 15, "passed": True, "hobbies": ["القراءة", "الرسم"], "phone": None}
text = json.dumps(student, ensure_ascii=False)
print(text)
print(type(text))
الناتج
{"name": "سارة", "age": 15, "passed": true, "hobbies": ["القراءة", "الرسم"], "phone": null}
<class 'str'>

لاحظ كيف تحولت True إلى true و None إلى null، وأن الناتج نص عادي يمكن حفظه في ملف أو إرساله عبر الإنترنت.

ولجعل النص مرتباً وسهل القراءة، أضف indent وحدد عدد مسافات الإزاحة:

print(json.dumps({"name": "عمر", "grades": [90, 85]}, ensure_ascii=False, indent=2))
الناتج
{
"name": "عمر",
"grades": [
90,
85
]
}

العملية العكسية بالدالة json.loads: تأخذ نص JSON وتعيد قيمة Python تستطيع التعامل معها كأي قاموس:

data = json.loads('{"city": "القاهرة", "temp": 31.5, "rainy": false}')
print(data["city"])
print(data["temp"] + 1)
print(data["rainy"])
الناتج
القاهرة
32.5
False

النص تحوّل إلى قاموس حقيقي: الرقم صار float يمكن الجمع عليه، و false صارت False.

الحفظ في ملف والقراءة منه

Section titled “الحفظ في ملف والقراءة منه”

هنا تجتمع JSON مع درس الملفات. للتعامل مع الملفات مباشرة نستخدم json.dump و json.load (بدون حرف s في آخرهما):

tasks = [
{"title": "مذاكرة Python", "done": True},
{"title": "ترتيب الغرفة", "done": False},
]
with open("tasks.json", "w", encoding="utf-8") as file:
json.dump(tasks, file, ensure_ascii=False, indent=2)
with open("tasks.json", encoding="utf-8") as file:
loaded = json.load(file)
for task in loaded:
status = "تمت" if task["done"] else "لم تتم"
print(task["title"], "-", status)
الناتج
مذاكرة Python - تمت
ترتيب الغرفة - لم تتم

بهذه الأسطر القليلة صار برنامجك يتذكر بياناته: يحفظ القائمة عند كل تغيير، ويقرؤها عند بداية التشغيل. وإذا فتحت ملف tasks.json بأي محرر نصوص، فستجده مرتباً ومقروءاً.

عندما يكون النص غير صالح

Section titled “عندما يكون النص غير صالح”

إذا حاولت تحويل نص لا يتبع قواعد JSON، فستطلق Python الخطأ json.JSONDecodeError. وأشهر سبب هو العلامات المفردة:

try:
json.loads("{'name': 'Ali'}")
except json.JSONDecodeError as e:
print("JSON غير صالح:", e)
الناتج
JSON غير صالح: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

الرسالة تقول إن اسم الخاصية يجب أن يكون بين علامتين مزدوجتين، وتخبرك بمكان المشكلة. التقط هذا الخطأ دائماً عندما تقرأ ملفاً قد يكون عدّله شخص بيده.

اكتب برنامجاً يحفظ قاموس إعدادات لعبة في ملف settings.json، ثم يقرؤه من جديد، ويغيّر مستوى الصوت إلى 40، ويحفظه مرة أخرى، ثم يطبع الإعدادات النهائية:

settings = {"player": "نور", "volume": 80, "dark_mode": True}
الناتج
{'player': 'نور', 'volume': 40, 'dark_mode': True}

ثم افتح الملف بمحرر النصوص وتأكد أن القيمة تغيّرت فيه.

  • الخلط بين dump و dumps: json.dumps(data, file) لن تكتب في الملف. تذكّر: حرف s للنصوص، وبدونه للملفات.
  • كتابة JSON بيدك بعلامات مفردة: {'name': 'Ali'} قاموس Python صحيح، لكنه ليس JSON صالحاً.
  • فاصلة زائدة في الآخر: [1, 2, 3,] مقبولة في Python ومرفوضة في JSON.
  • حفظ أنواع لا تدعمها JSON: المجموعات set والكائنات من كلاساتك لا تتحول تلقائياً، وستظهر TypeError. حوّلها أولاً إلى قائمة أو قاموس.

سؤال

أي دالة تحوّل نص JSON إلى قاموس Python؟

سؤال

كيف تُكتب القيمة None في JSON؟

  • JSON صيغة نصية لتبادل البيانات تفهمها كل لغات البرمجة.
  • json.dumps تحوّل قيمة Python إلى نص، و json.loads تحوّل النص إلى قيمة Python.
  • json.dump و json.load تكتبان في ملف وتقرآن منه مباشرة.
  • استخدم ensure_ascii=False للعربية و indent=2 لملف مرتب.
  • التقط json.JSONDecodeError عند قراءة نص قد يكون غير صالح.