بعد أن تتعلم قراءة وكتابة ملفات JSON في Python، قد يظهر لك خطأ مزعج اسمه JSONDecodeError. هذا الخطأ يظهر غالبًا عندما يحاول البرنامج قراءة ملف JSON، لكن محتوى الملف ليس مكتوبًا بصيغة JSON صحيحة.
في هذا المقال من سلسلة مشكلة وحل في بايثون سنتعلم معنى خطأ JSONDecodeError، وسبب ظهور رسالة مثل Expecting value أو Expecting property name enclosed in double quotes، وكيف تصلح ملف JSON خطوة بخطوة بطريقة مناسبة للمبتدئين.
{getToc} $title={محتوى المقال}
الفكرة ببساطة: خطأ JSONDecodeError يعني أن Python حاول قراءة نص أو ملف على أنه JSON، لكنه وجد أن التنسيق غير صحيح أو أن الملف فارغ. {alertInfo}
شكل الخطأ
قد يظهر الخطأ بهذا الشكل عند استخدام json.load أو json.loads:
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
وقد يظهر أيضًا بهذا الشكل:
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes
أو بهذا الشكل:
json.decoder.JSONDecodeError: Extra data
كل هذه الرسائل تعني أن Python لم يستطع فهم محتوى JSON بالشكل المتوقع.
مثال كود يسبب JSONDecodeError
لنفترض أن لديك ملفًا اسمه data.json، وتريد قراءته:
import json
with open("data.json", "r", encoding="utf-8") as file:
data = json.load(file)
print(data)
إذا كان ملف data.json فارغًا، أو يحتوي على JSON غير صحيح، سيظهر خطأ JSONDecodeError.
ما معنى JSONDecodeError؟
كلمة Decode هنا تعني أن Python يحاول تفسير النص وتحويله من صيغة JSON إلى بيانات Python مثل dict أو list.
إذا كان النص مكتوبًا بطريقة صحيحة، يتم التحويل بنجاح. أما إذا كان النص فارغًا أو فيه خطأ في علامات التنصيص أو الفواصل أو الأقواس، فلن يستطيع Python قراءته، فيظهر خطأ JSONDecodeError.
مثال JSON صحيح:
{
"name": "Ali",
"age": 25
}
مثال JSON غير صحيح:
{
"name": "Ali",
"age": 25,
}
الخطأ هنا أن هناك فاصلة زائدة بعد آخر عنصر.
أشهر أسباب JSONDecodeError
هذا الخطأ له أسباب كثيرة، لكن أكثرها شيوعًا عند المبتدئين:
- ملف JSON فارغ.
- وجود فاصلة زائدة بعد آخر عنصر.
- استخدام علامات تنصيص مفردة بدل المزدوجة.
- نسيان قوس أو فاصلة.
- كتابة أكثر من JSON object في نفس الملف بدون قائمة.
- محاولة قراءة ملف ليس JSON أصلًا.
- استخدام
json.loadsعلى نص غير صالح. - وجود تعليقات داخل ملف JSON.
السبب الأول: ملف JSON فارغ
من أكثر أسباب الخطأ شيوعًا أن يكون الملف فارغًا تمامًا. إذا حاولت قراءة ملف فارغ باستخدام json.load سيظهر غالبًا:
JSONDecodeError: Expecting value: line 1 column 1 (char 0)
لأن Python يتوقع أن يجد قيمة JSON في بداية الملف، لكنه لم يجد شيئًا.
الحل أن تضع محتوى JSON صحيحًا داخل الملف، مثل:
{}
أو:
[]
أو بيانات فعلية:
{
"name": "Ali",
"age": 25
}
السبب الثاني: استخدام علامات تنصيص مفردة
في Python يمكنك كتابة Dictionary بعلامات تنصيص مفردة أو مزدوجة، لكن في JSON يجب استخدام علامات تنصيص مزدوجة حول المفاتيح والنصوص.
هذا صحيح في Python كـ Dictionary:
{
'name': 'Ali',
'age': 25
}
لكنه غير صحيح كملف JSON. الصحيح في JSON:
{
"name": "Ali",
"age": 25
}
مهم: JSON ليس نفس Dictionary في Python تمامًا. قد يتشابهان في الشكل، لكن JSON له قواعد أكثر صرامة، وأهمها استخدام علامات التنصيص المزدوجة. {alertWarning}
السبب الثالث: وجود فاصلة زائدة
في JSON لا تضع فاصلة بعد آخر عنصر. هذا مثال خاطئ:
{
"name": "Ali",
"age": 25,
}
الصحيح:
{
"name": "Ali",
"age": 25
}
هذه الفاصلة الزائدة من أكثر الأخطاء التي تسبب JSONDecodeError.
السبب الرابع: كتابة تعليقات داخل JSON
في ملفات Python يمكنك كتابة تعليقات باستخدام #، لكن ملفات JSON لا تدعم التعليقات.
هذا JSON غير صحيح:
{
# اسم المستخدم
"name": "Ali"
}
الصحيح أن تحذف التعليق:
{
"name": "Ali"
}
إذا أردت وضع ملاحظات، اجعلها قيمة عادية داخل JSON:
{
"name": "Ali",
"note": "مستخدم تجريبي"
}
السبب الخامس: أكثر من كائن JSON في نفس الملف
لا يمكنك كتابة أكثر من كائن JSON منفصلين في نفس الملف بهذا الشكل:
{
"name": "Ali"
}
{
"name": "Sara"
}
قد يؤدي هذا إلى خطأ مثل:
JSONDecodeError: Extra data
الصحيح أن تضع البيانات داخل قائمة:
[
{
"name": "Ali"
},
{
"name": "Sara"
}
]
السبب السادس: استخدام True و False و None بدل صيغة JSON
في Python نستخدم True و False و None، لكن في JSON الصيغة تكون مختلفة:
| في Python | في JSON |
|---|---|
True |
true |
False |
false |
None |
null |
هذا JSON غير صحيح:
{
"active": True,
"deleted": None
}
الصحيح:
{
"active": true,
"deleted": null
}
إذا كتبت البيانات داخل Python كـ Dictionary ثم استخدمت json.dump، فسيحول Python القيم تلقائيًا إلى صيغة JSON الصحيحة.
طريقة حل JSONDecodeError خطوة بخطوة
عندما يظهر لك الخطأ، لا تحاول تغيير الكود عشوائيًا. اتبع هذه الخطوات:
- اقرأ رسالة الخطأ جيدًا.
- لاحظ رقم السطر والعمود إن ظهر في الرسالة.
- افتح ملف JSON وتأكد أنه ليس فارغًا.
- تأكد أن المفاتيح والنصوص داخل علامات تنصيص مزدوجة.
- احذف أي فاصلة زائدة بعد آخر عنصر.
- تأكد أن الأقواس مكتملة.
- تأكد أن الملف يحتوي على كائن واحد أو قائمة واحدة.
- جرّب فحص الملف في محرر يدعم JSON.
استخدام try و except للتعامل مع الخطأ
إذا كان احتمال وجود ملف JSON غير صالح واردًا، يمكنك استخدام try و except لعرض رسالة واضحة بدل توقف البرنامج.
import json
try:
with open("data.json", "r", encoding="utf-8") as file:
data = json.load(file)
print(data)
except json.JSONDecodeError:
print("ملف JSON غير صحيح أو لا يمكن قراءته.")
هنا استخدمنا:
except json.JSONDecodeError:
حتى نتعامل فقط مع أخطاء JSON، بدل التقاط كل الأخطاء بدون تمييز.
التعامل مع الملف الفارغ قبل json.load
إذا كنت تتوقع أن الملف قد يكون فارغًا، يمكنك قراءة النص أولًا والتأكد منه قبل تحويله إلى JSON.
import json
from pathlib import Path
file_path = Path("data.json")
if file_path.exists() and file_path.read_text(encoding="utf-8").strip():
data = json.loads(file_path.read_text(encoding="utf-8"))
print(data)
else:
print("الملف غير موجود أو فارغ.")
هذا الأسلوب مفيد عندما يكون الملف قد أُنشئ لكنه لا يحتوي على بيانات بعد.
إنشاء ملف JSON افتراضي إذا كان فارغًا
في بعض المشاريع، الأفضل أن تنشئ بيانات افتراضية إذا كان ملف JSON غير موجود أو فارغ. مثلًا ملف إعدادات:
import json
from pathlib import Path
file_path = Path("settings.json")
default_settings = {
"theme": "dark",
"language": "Arabic"
}
if not file_path.exists() or not file_path.read_text(encoding="utf-8").strip():
file_path.write_text(
json.dumps(default_settings, ensure_ascii=False, indent=4),
encoding="utf-8"
)
settings = json.loads(file_path.read_text(encoding="utf-8"))
print(settings)
هذا المثال يمنع البرنامج من محاولة قراءة ملف فارغ.
مقارنة بين JSON الصحيح والخاطئ
| الخطأ | غير صحيح | الصحيح |
|---|---|---|
| علامات تنصيص مفردة | {'name': 'Ali'} |
{"name": "Ali"} |
| فاصلة زائدة | {"name": "Ali",} |
{"name": "Ali"} |
| قيمة Python داخل JSON | {"active": True} |
{"active": true} |
| تعليق داخل JSON | {"name": "Ali" # comment} |
{"name": "Ali"} |
| أكثر من كائن منفصل | {...} {...} |
[{...}, {...}] |
أفضل ممارسات لتجنب JSONDecodeError
- استخدم
json.dumpوjson.dumpsلإنشاء JSON بدل كتابته يدويًا قدر الإمكان. - لا تضع فاصلة بعد آخر عنصر.
- استخدم علامات تنصيص مزدوجة في ملفات JSON.
- لا تكتب تعليقات داخل ملفات JSON.
- تأكد أن الملف ليس فارغًا قبل قراءته.
- استخدم
encoding="utf-8"عند التعامل مع العربية. - استخدم
try/exceptعند قراءة ملفات قد تكون غير صالحة. - ضع البيانات المتعددة داخل قائمة واحدة بدل عدة كائنات منفصلة.
مثال عملي كامل: قراءة JSON بأمان
هذا مثال يجمع بين فحص وجود الملف، فحص أنه ليس فارغًا، والتعامل مع خطأ JSONDecodeError.
import json
from pathlib import Path
file_path = Path("data.json")
if not file_path.exists():
print("الملف غير موجود.")
elif not file_path.read_text(encoding="utf-8").strip():
print("الملف فارغ.")
else:
try:
data = json.loads(file_path.read_text(encoding="utf-8"))
print(data)
except json.JSONDecodeError as error:
print("صيغة JSON غير صحيحة.")
print(error)
هذا الكود مناسب كبداية جيدة عندما تبني مشروعًا يقرأ بيانات من ملف JSON.
روابط داخلية مفيدة من بايثون العرب
- سلسلة مشكلة وحل في بايثون
- أساسيات بايثون 29: شرح مكتبة json في Python للمبتدئين
- أساسيات بايثون 22: التعامل مع الملفات في Python
- حل خطأ FileNotFoundError في Python عند فتح الملفات
- تنظيم ملفات مشروع Python بعد الأساسيات
مصادر خارجية مفيدة للتوسع
الخلاصة
خطأ JSONDecodeError يظهر عندما يحاول Python قراءة JSON غير صحيح. قد يكون الملف فارغًا، أو يحتوي على فاصلة زائدة، أو علامات تنصيص مفردة، أو تعليقات، أو أكثر من كائن JSON منفصل.
أفضل طريقة لتجنب هذا الخطأ هي أن تنشئ JSON باستخدام دوال Python مثل json.dump و json.dumps بدل كتابته يدويًا قدر الإمكان. وعند قراءة ملفات خارجية، استخدم try/except وافحص أن الملف موجود وغير فارغ.
الخلاصة العملية: إذا ظهر لك JSONDecodeError، افحص محتوى ملف JSON أولًا قبل تعديل الكود؛ لأن المشكلة غالبًا في تنسيق الملف وليس في Python نفسها. {alertSuccess}
أسئلة شائعة مع إجاباتها
ما معنى JSONDecodeError في Python؟
يعني أن Python حاول قراءة نص أو ملف كـ JSON، لكنه وجد أن التنسيق غير صحيح أو أن الملف فارغ.
ما سبب رسالة Expecting value؟
غالبًا تظهر عندما يكون ملف JSON فارغًا أو عندما لا يبدأ المحتوى بقيمة JSON صحيحة مثل كائن أو قائمة.
هل يمكن استخدام علامات تنصيص مفردة في JSON؟
لا. ملفات JSON تتطلب علامات تنصيص مزدوجة حول المفاتيح والنصوص.
هل JSON يدعم التعليقات؟
لا. JSON لا يدعم التعليقات، لذلك وجود تعليق داخل ملف JSON قد يسبب خطأ عند القراءة.
ما الفرق بين JSONDecodeError و FileNotFoundError؟
FileNotFoundError يعني أن الملف غير موجود أو المسار خطأ، أما JSONDecodeError فيعني أن الملف موجود لكن محتواه ليس JSON صحيحًا.
كيف أتجنب JSONDecodeError؟
استخدم json.dump و json.dumps لإنشاء JSON، وافحص أن الملف غير فارغ، وتأكد من عدم وجود فاصلة زائدة أو علامات تنصيص مفردة أو تعليقات داخل JSON.



