يشرح برنامج تعليمي كيفية بناء عملية تسلسل JSON بلغة Python قادرة على التعامل مع أنواع البيانات المخصصة، وتحمل البيانات المشوهة، والتكيف مع تطور المخططات. الهدف هو تمرير مجموعات البيانات بين الملفات والعمليات والخدمات المصغرة وواجهات برمجة التطبيقات دون أن يتوقف خط المعالجة عند أول شذوذ.
وفقًا للمقال، فإن جزءًا صغيرًا فقط من وقت مهندس تعلم الآلة يُكرَّس لكتابة بنية النموذج. أما الباقي فيذهب إلى «سباكة البيانات» («data plumbing»)، أي تنظيف البيانات ومعالجتها مسبقًا وتحويلها. جزء من هذا العمل يتضمن تسلسل البيانات، وتحويلها إلى نص لتخزينها أو نقلها، ثم فك تسلسلها، أي إعادة بنائها إلى كائنات Python.
تكمن المشكلة الأساسية في حدود تنسيق JSON، الذي لا يعرف سوى أنواع أساسية قليلة. قاموس تكوين تجربة يحتوي على Enum، أو set، أو Path، أو datetime يتسبب في حدوث خطأ بمجرد استدعاء json.dumps()، مع رسالة «TypeError: Object of type ModelType is not JSON serializable».
مُشفر مخصص
تتمثل الخطوة الأولى في تعريف فئة ترث من json.JSONEncoder وتعيد تعريف طريقة default() الخاصة بها. لكل نوع إشكالي، تشير شرط من نوع isinstance() إلى التحويل الذي يجب إجراؤه. يتم تحويل datetime إلى قاموس يحتوي على قيمة بتنسيق ISO، وتحويل set إلى قوائم، وتحويل Path إلى سلاسل نصية، وتحويل Enum إلى قيمتها.
تفصيل واحد يلعب دورًا مركزيًا: يضيف المُشفر مفتاح «__type__» إلى الكائنات التي قد تفقد طبيعتها الأصلية، مثل set المحول إلى قائمة. بمجرد تمريره إلى json.dumps() عبر الوسيط cls، يتم تسلسل قاموس المثال دون خطأ، ويظهر datetime بالشكل «2026-09-28T14:26:10.328310».
وحدة فك تشفير متسامحة مع الأخطاء
في الاتجاه المعاكس، يتم تمرير الدالة robust_decoder إلى json.loads() عبر الوسيط object_hook. يتم استدعاؤها على كل قاموس متداخل وتعيد بناء الكائن الأصلي عندما يكون المفتاح «__type__» موجودًا. يتم وضع عمليات التحويل داخل كتلة try، التي تلتقط أخطاء ValueError و TypeError.
في حالة وجود بيانات مشوهة، تسجل الدالة تحذيرًا عبر وحدة logging وتُرجع القيمة الأولية، دون مقاطعة المعالجة. يوضح المقال أنه يمكن استبدال هذا السلوك بقيمة افتراضية بديلة أو قاموس خطأ محدد. بعد فك التسلسل، يتم التعرف على التاريخ بشكل صحيح كـ datetime والقائمة كـ set.
إدارة تطور المخططات
تتغير مخططات البيانات الوصفية للنماذج غالبًا: تتم إضافة معاملات فائقة، ويتم التخلي عن أخرى، ويتم إعادة تسمية بعض المقاييس. للتعامل مع ذلك، يقترح المؤلف دالة مصنع، load_experiment_config()، التي تحمل JSON باستخدام وحدة فك التشفير ثم تطبق القيم الافتراضية باستخدام get().
يتناول المثال معاملًا فائقًا «learning_rate» غير موجود في التكوين القديم، ويتم تعيين القيمة الافتراضية 0.001 له. يمكن تطبيق نفس المبدأ على أي معلمة جديدة. يذكر المقال أيضًا إمكانية حذف الحقول القديمة أثناء التحميل. عند تطبيقه على التكوين الأصلي، يعيد التحميل الأنواع المتوقعة: عدد صحيح للمعرف، وset للمتغيرات، وPosixPath للمسار، وdatetime للطابع الزمني، وعدد عشري لمعدل التعلم.





