تعلّم بايثون في عطلة نهاية الأسبوع: من الصفر إلى مشروع متكامل
كيف يمكننا تعلم لغة برمجة جديدة بسرعة؟ في هذه المقالة، سنشارك تجربتنا في نهاية الأسبوع في تعلم بايثون من خلال بناء مشروع متكامل.
كيف يمكننا تعلم لغة برمجة جديدة بسرعة؟ في هذه المقالة، سنشارك تجربتنا في نهاية الأسبوع في تعلم بايثون من خلال بناء مشروع متكامل.
Logto، كخدمة هوية، يوفر تجربة سلسة عبر لغات البرمجة والأطر المختلفة أمر ضروري. وغالباً ما يتضمن ذلك إنشاء مجموعات تطوير البرمجيات (SDKs). ومع ذلك، عندما تكون لغة البرمجة خارج منطقنا التقني ويفتقد فريقنا الخبرة، يصبح إنشاء SDK قوي تحدياً.
وشكّلت بايثون مثل هذا التحدي لنا. على الرغم من وجود العديد من مستخدمي بايثون، لم نكن نمتلك SDK لبايثون، وهو أمر كان يثير القلق باستمرار. قررت معالجة هذا، وبدأت في سد هذه الفجوة.
على الرغم من أن لدي سنوات من الخبرة البرمجية، إلا أن بايثون يبقى منطقة غير مستكشفة بالنسبة لي. بينما كنت قد لعبت ببايثون 2 لفترة وجيزة لكتابة نصوص بسيطة منذ سنوات، كانت معرفتي قديمة. ومع ذلك، كان الوقت قد حان للتعمق!
في تجربتي، النهج الأكثر فعالية لتعلم لغة برمجة جديدة هو بناء مشروع متكامل. لحسن الحظ، كان هدفنا واضحاً: بناء SDK لبايثون لتطبيقات الويب لLogto.
بدلاً من القفز إلى الشيفرة البرمجية، دعونا نقسم الأمر. إليك القائمة:
يبدو أن المهمة 1 بها العمل الأكثر، لذا نحتاج إلى تأكيد النطاق ومتابعة تقسيمه. هذه الخطوة ضرورية لتأمين حدود المشروع، وتجنب توسع النطاق والهندسة المفرطة.
عمل الفريق السابق وفر لي الكثير من الوقت:
بالاعتماد على هذه الموارد، يمكنني رؤية صورة واضحة لما يجب القيام به. بينما التفاصيل أبعد من نطاق هذه المقالة، دعونا نمضي قُدماً.
أستخدم جهاز Mac، لذا فإن بايثون مثبت بالفعل. مع ذلك، كنت أتساءل عما إذا كان هناك طريقة أفضل لإدارة إصدارات بايثون (لقد سمعت ألم توافق الإصدار)، تماماً مثل nvm لNode.js. سرعان ما وجدت pyenv وبدأت مباشرة في تثبيته.
المهمة التالية على جدول الأعمال: مدير الحزم والاعتمادات. عادة ما يكونان مرتبطين. فلماذا لا pip (الإعداد الافتراضي لبايثون)؟ إذا ألقيت نظرة على requirements.txt، ستجد أنه مجرد قائمة بحزم مع إصدارات. هذا ليس كافياً لSDK الذي قد يستخدمه مشاريع أخرى. على سبيل المثال، قد نحتاج إلى إضافة بعض الحزم للتطوير ولكن لا نريد تضمينها في SDK النهائي. requirements.txt بسيط جداً للتعامل مع هذا.
أحد الفوائد عندما يكون لديك لغات برمجة أخرى في منطقك التقني هو أنه يمكنك البحث عن "المكافئ لبايثون". لذا بحثت عن "المكافئ لحزمة.json لبايثون" ووجدت Poetry كمرشح رائع:
pyproject.toml، شبيه بـ package.json في Node.js.غالباً ما تُشمل واجهات الأوامر الحديثة (CLI) على أمر init الذي يتم تخصيصه للمشاريع الجديدة. كذلك يتم فعل الشيء نفسه مع Poetry. قمت بتشغيل الأمر وأنشأ لي ملف pyproject.toml.
وأخيراً، حان الوقت لكتابة الكود. البداية ببرنامج "Hello, World!" الكلاسيكي دائماً اختيار جيد. عند تعلم لغة برمجة جديدة، لا تكون البيئات المتكاملة للتطوير (IDE) الضرورية دائماً؛ محرر مدعوم من مجتمع قوي، مثل VS Code، يكون كافٍ تماماً.
بالنظر إلى أن تركيز SDK على تطبيقات الويب، بدأت بخادم ويب بسيط باستخدام إطار العمل الشهير Flask.
باستخدام قدرات Poetry، يمكن تثبيت Flask ببساطة عن طريق تشغيل poetry add flask. ثم، باتباع دليل البدء السريع الرسمي لـ Flask، قمت بتأليف ملف 'hello.py' مع المقتطف التالي:
تشغيل الخادم عبر flask --app hello run والتنقل إلى http://localhost:5000 على المتصفح أدى إلى النتيجة المطلوبة. لقد نجح!
كمبتدئ، لم أكن مستعجلًا لكتابة المزيد من الكود. بدلاً من ذلك، هناك الكثير من المعلومات التي يجب استيعابها من مقتطف الكود:
from x import y لاستيراد وحدة أو صنف.new.@app.route يعمل كمزين يسجل دالة كموجه للطرق.
def.كما ترى، إذا حاولنا فهم كل سطر من الكود بدلاً من "جعل الأمر يعمل فقط"، يمكننا أن نتعلم الكثير من خلاله. في الوقت ذاته، وثائق Flask الرسمية شرحت المقتطف بتفصيل.
الآن حان الوقت لبدء المشروع. قريبًا قمت بتعريف صنف LogtoClient وحاولت إضافة بعض الخصائص والأساليب للشعور باللغة:
بعد ذلك، دمج الصنف مع Flask:
بدأ يبدو الأمر كمشروع حقيقي. لكنني شعرت أن شيئًا ما ينقص: نظام النوع.
نظرًا لأنه SDK، فإن تضمين نظام النوع سيساعد المستخدمين على فهم API وتقليل فرصة الأخطاء عند التطوير.
قدم بايثون إرشادات النوع في الإصدار 3.5. ليس بقدر قوة TypeScript، لكنه أفضل من لا شيء. أضفت بعض إرشادات النوع إلى صنف LogtoClient:
يبدو الأمر أفضل بكثير الآن. لكن التحدي ظهر عندما يتعلق الأمر بنوع معقد مثل كائن ذو مفاتيح محددة مسبقًا. على سبيل المثال، نحتاج إلى تعريف صنف LogtoConfig لتمثيل كائن الإعدادات:
يبدو هذا جيداً، لكننا قريبًا نحتاج إلى مواجهة مشاكل الترميز وفك الترميز والتحقق من الكائن من JSON.
بعد بعض البحث، اخترت pydantic كحل. إنها مكتبة تحقق من البيانات التي تعمل مع إرشادات النوع. وتدعم وظائف JSON متنوعة دون اتباع شيفرة نموذجية قابلة للتكرار.
وهكذا، يمكن إعادة كتابة صنف LogtoConfig كما يلي:
كما علَّمتني عن الوراثة بين الأصناف في بايثون من خلال إضافة أقواس بعد اسم الصنف.
ضمن SDK Logto، نحتاج إلى إجراء طلبات HTTP إلى خادم Logto. إذا كان لديك خبرة مع JavaScript، فإن عبارة "جحيم الاستدعاء البيني" قد ترن في ذهنك. إنها مشكلة شائعة عند التعامل مع العمليات غير المتزامنة. تقدم لغات البرمجة الحديثة حلولاً مشابهة مثل Promise أو coroutine.
لحسن الحظ، تمتلك بايثون حلاً مدمجًا للـ async و await. قبل استخدامها، تأكد من التوافق مع الأطر الشائعة. في Flask، يمكن القيام بذلك بتثبيت async الإضافي واستخدام async def بدلاً من def:
ثم يمكننا استخدام await لانتظار نتيجة العملية غير المتزامنة.
طلبات HTTP موضوع شيق. تقريبًا كل لغة برمجة تمتلك حلاً أصليًا، ولكن عادة ما يستخدم المطورون مكتبة طرف ثالث لتيسير الاستخدام. بعض الأمثلة:
XMLHttpRequest مقابل fetch مقابل axiosURLSession مقابل AlamofireHttpURLConnection مقابل OkHttpوهذا صحيح أيضًا لبايثون. قراري كان استخدام aiohttp لدعمها لـ async و await، إلى جانب شعبيتها.
قبل Copilot، الآن يجب أن نأتي إلى الجزء الشاق من كتابة منطق الأعمال. بمساعدة اتفاقية SDK وSDKs الأخرى، يمكنني كتابة تعليقات وصفية لكل أسلوب قبل كتابة الكود.
يُضيف مزيدًا من وضوح الشيفرة البرمجية، كما يساعد المطورين على فهم API مباشرة في بيئة التطوير المتكاملة أو المحرر عبر الذكاء البرمجي.
على سبيل المثال، ضع في اعتبارك أسلوب generateCodeChallenge، يمكن كتابة التعليقات كما يلي:
هذا كان دعوة ممتازة للنماذج اللغوية الكبيرة (LLMs): تجميع التعريفات للأساليب بواسطة تعليقات واضحة. ولم يُخفق Copilot:
قد تكون هناك حاجة إلى بعض التعديلات، لكن لا يهم. لقد غيرت اللعبة بالفعل.
هذا هو التقدم الذي تم تحقيقه في اليوم الأول بشكل كبير. كان يوماً طويلاً، لكن بإستخدام الأدوات والتقنيات الحديثة، كان أفضل بكثير مما توقعت.
استناداً إلى عمل اليوم الأول، تم إتمام منطق الأعمال بسرعة. لكن بالنسبة للـ SDK، فإنه لا يزال غير كافٍ. ها هي المهام لليوم الثاني:
اختبارات الوحدة أنقذتنا عدة مرات، لذا لن أتخطاها. ها هي الاعتبارات الشائعة عند كتابة اختبارات الوحدة:
مع هذه الأسئلة في الاعتبار، وجدت أن الوحدة الافتراضية unittest قصيرة في بعض الحالات. لذا اخترت pytest كإطار اختبار. يدعم الاختبارات غير المتزامنة ويبدو ناضجًا بما يكفي.
كشف الرحلة بعض المفاهيم الجديدة المثيرة مثل fixture بالنسبة لي. يمكن أن يستفيد هذا أيضًا من طريقة التفكير عند كتابة الشيفرة البرمجية بلغات أخرى.
لكل لغة أنماط تنسيق شيفراتها البرمجية الخاصة. بالنسبة لي، فإن التنسيق المتسق يمكن أن يجعلني سعيداً ومرتاحاً؛ كما أنه مفيد للمراجعة والتعاون.
بدلاً من تصفح الجدل حول