3.1الوحدات (modules) والحزم (packages) والمكتبة المعيارية
الأساسي في 30 ثانية
- الوحدة (module) = ملف .py واحد، والحزمة (package) = مجلد وحدات : نعيد الاستعمال عبر import بدل النسخ واللصق — from stats import frequence، والاسم المستعار import x as y.
- المكتبة المعيارية صندوق مدفوع مسبقا : pathlib، datetime، collections، itertools، argparse، sqlite3 — مختبَرة، موثقة، دون اعتمادية للتثبيت.
- كتلة __main__ تفصل الاستعمال المستورَد عن الاستعمال المباشر : العرض لا يشتغل إلا عند التنفيذ المباشر، أبدا عند الاستيراد — انتهت الآثار الجانبية.
حالة مصغرة متسلسلة — نبيل يرتب سكربتات التحليل
نبيل، محلل بيانات مبتدئ في الجزائر، يحلل المبيعات بثلاثة سكربتات تنسخ دوال التنظيف نفسها : تصحيح في الجزائر-وسط، منسي في نسخة وهران، زيف تقريرا. رتب المشترك في وحدة (module) stats.py (دالة frequence بـ Counter)، واستورد عبر from stats import frequence، وحمى العرض بـ if __name__ == "__main__"، واستبدل ترقيع التواريخ بـ datetime و pathlib من المعيارية. كود واحد، وثلاثة تحليلات صحيحة.
هذه الحالة نفسها تعود في الدرس والمخطط والنص الجاهز وتحدي 48 ساعة.
1. الوحدات (modules) والحزم (packages) والاستيرادات النظيفة
عندما يكبر المشروع، يصبح كل شيء في ملف واحد غير قابل للتدبير : الوحدة (module) ملف .py قابل لإعادة الاستعمال (import stats ثم stats.frequence())، والحزمة (package) مجلد يجمع وحدات متجانسة. نستورد في رأس الملف، مجمعة (معيارية ← طرف ثالث ← محلية)، بمطلق (from monapp import stats)، مع الصيغ import math، وfrom math import sqrt، وimport x as y — وأبدا from x import * التي تلوث فضاء الأسماء.
كتلة if __name__ == "__main__": تجعل الملف قابلا للتنفيذ وقابلا للاستيراد معا : الكود تحتها لا يشتغل إلا عند الإطلاق المباشر (python stats.py)، لا عند الاستيراد. يضع نبيل فيها عرضه على عينة مبيعات الجزائر : مستورَدا، لا تقدم الوحدة سوى دوال ؛ ومنفذة، تعرض المثال. والاستيرادات الدائرية (A يستورد B الذي يستورد A) تشير إلى تقطيع يجب مراجعته، لا إلى حيلة تُفرَض.
2. المكتبة المعيارية : تحقق قبل أن تثبت
تأتي بايثون بالبطاريات : pathlib (المسارات الحديثة)، وdatetime (التواريخ والساعات)، وcollections (Counter، defaultdict)، وitertools (التكرارات)، وargparse (واجهات سطر الأوامر)، وsqlite3 (قاعدة مضمنة)، دون نسيان os، sys، json، random، math. قبل أي pip install، يتحقق نبيل من الصندوق المعياري : عد المبيعات حسب المدينة بـ Counter، وسرد مجلد بـ pathlib، وتأريخ تصدير بـ datetime.
منعكس المحترف : المعيارية أولا، وPyPI بعدها. المعيارية مختبَرة وموثقة ودون اعتمادية — كل مكتبة خارجية تضيف كلفة (تثبيت، إصدارات، صيانة). لا يخرج نبيل pip إلا لما لا تغطيه المعيارية (التحليل الجدولي، رسوم المستوى 4)، ويبقي استيراداته مطلقة ومجمعة ليبقى مقروءا.
🔎 مثال ملموس — إحصاء المبيعات في وحدة محمية
يعد نبيل المبيعات حسب المدينة من وحدة (module) قابلة لإعادة الاستعمال.
from collections import Counter
def frequence(contacts):
return Counter(c["ville"] for c in contacts)
if __name__ == "__main__":
echantillon = [{"ville": "Alger"}, {"ville": "Oran"}, {"ville": "Alger"}]
print(frequence(echantillon))
القراءة : مستورَدا = دوال فقط ؛ ومنفذا مباشرة = عرض على العينة.
الدرس : كتلة __main__ تحمي من الآثار الجانبية عند الاستيراد.
مفردات القسم
- الوحدة (module)
- ملف .py قابل لإعادة الاستعمال : نصل إليه بـ import mon_module، ثم mon_module.fonction().
مثال بسيط: ملف stats.py لنبيل المستورَد في تحليلاته الثلاثة.
ما ليس كذلك: نسخ-لصق الدالة في كل سكربت.
رد فعل: رتب المشترك في وحدة (module) منذ النسخة الثانية.
- الحزمة (package)
- مجلد يجمع وحدات (modules) متجانسة لهيكلة مشروع.
مثال بسيط: مجلد monapp/ فيه stats.py و nettoyage.py.
ما ليس كذلك: عشرون ملف .py مبعثرة دون مجلد.
رد فعل: جمع حسب الموضوع، والاستيراد بمطلق.
- import / from / as
- تحميل كود قابل لإعادة الاستعمال : import math، و from math import sqrt، و import x as y ؛ وأبدا from x import *.
مثال بسيط: عبارة from stats import frequence عند نبيل.
ما ليس كذلك: عبارة from stats import * التي تلوث فضاء الأسماء.
رد فعل: استيراد صريح، في الرأس، مجمع.
- المكتبة المعيارية
- وحدات (modules) مرفقة مع بايثون : datetime، pathlib، collections، itertools، argparse، sqlite3، os، json، random، math…
مثال بسيط: Counter للمدن، وdatetime لتأريخ تصدير نبيل.
ما ليس كذلك: تثبيت حزمة خارجية لما يفعله Counter أصلا.
رد فعل: تحقق من المعيارية قبل pip install.
- if __name__ == "__main__"
- كتلة لا تنفذ إلا عند الإطلاق المباشر، لا عند الاستيراد : تفصل العرض عن الدوال.
مثال بسيط: عرض نبيل على العينة، صامت عند الاستيراد.
ما ليس كذلك: print اختبار يعاد تشغيله مع كل استيراد.
رد فعل: __main__ منهجية لكل عرض.
في التطبيق — التنظيم في وحدات (modules) واستغلال المعيارية
- أنشئوا وحدة (module) « stats.py » بدالتين (مثلا frequence، moyenne)، ثم استوردوها في ملف آخر ونادوا دوالها.
- استكشفوا المعيارية : datetime.now() لتأريخ تصدير، وCounter لعد المدن، وpathlib لسرد مجلد.
- استعملوا « from module import fonction » والاسم المستعار « import x as y » : قارنوا مقروئية الأسلوبين.
- أضيفوا كتلة « if __name__ == '__main__' » بعرض : تحققوا أنها لا تنفذ عند الاستيراد.
نص جاهز للقول — عرض وحدته (30 ثانية)
« المشترك يعيش في stats.py : دالة frequence بـ Counter، مستورَدة عبر from stats import frequence، والعرض محمي تحت __main__. التواريخ والمسارات عبر datetime و pathlib من المعيارية، واستيرادات مطلقة في الرأس، وأبدا نجمة. كود واحد لثلاثة تحليلات. »
يُقال في المراجعة ؛ ويُعرَض الاستيراد وكتلة __main__.
نموذج نسخ-لصق — وحدة (module) + استيراد محمي
from collections import Counter
from datetime import datetime
from pathlib import Path
def frequence(contacts):
return Counter(c["ville"] for c in contacts)
def dater_export():
return datetime.now().strftime("%Y-%m-%d")
if __name__ == "__main__":
print(frequence([{"ville": "Alger"}]))
print(sorted(Path(".").iterdir()))
مستقل
تكفي وحدة (module) stats.py بـ Counter لتأمين التقارير الشهرية.
مقاولة صغيرة في الجزائر
يشارك نبيل وحدته بين تحليلي الجزائر-وسط ووهران دون نسخ.
فريق منتج
فرض استيرادات مطلقة مجمعة و __main__ منهجية لوحدات قابلة للاستيراد.
مبتدئ
هذا الأسبوع : وحدة واحدة، ودالتان، وعرض تحت __main__.
✓ ممارسات جيدة
- وضع كتلة __main__ منهجية لكل عرض أو اختبار يدوي.
- التحقق من المكتبة المعيارية قبل تثبيت أي شيء.
- الاستيراد بمطلق، مجمع (معيارية ← طرف ثالث ← محلية)، وأبدا بـ *.
✗ أخطاء شائعة
- نسخ-لصق دالة بين الملفات بدل جعلها وحدة (module).
- استعمال from x import * (أسماء مسحوقة، وأصل غير مقروء).
- ترقيع استيرادات دائرية بدل إعادة تقطيع الوحدات.
النقاط الأساسية
- الوحدة (module) = ملف .py واحد ؛ والحزمة (package) = مجلد وحدات : نستورد (from/as) بدل النسخ.
- المكتبة المعيارية تغطي التواريخ والمسارات والعد والواجهات والقاعدة المضمنة… دون تثبيت شيء.
- if __name__ == '__main__' يفصل الكود القابل للتنفيذ (العرض) عن الكود القابل للاستيراد (الدوال).
- استيرادات نظيفة : في الرأس، مجمعة، مطلقة، وأبدا نجمة ؛ والدائرية = تقطيع يُراجَع.
تحدي 48 ساعة — طبّق غدا
استخرجوا دالة مكررة واحدة في وحدة (module) يستوردها سكربتان، مع عرض تحت __main__.
- أميز الوحدة (module) (ملف) عن الحزمة (package) (مجلد).
- استيراداتي مطلقة ومجمعة ودون نجمة.
- عرضي تحت __main__ لم يعد يشتغل عند الاستيراد.
أسئلة شائعة
ما الفرق بين « import math » و « from math import sqrt » ؟
import math يحمل الوحدة (module) كاملة، وتُنادى بـ math.sqrt() (أصل صريح). وfrom math import sqrt لا يستورد سوى sqrt، وتُنادى مباشرة. الصيغة الأولى تُقرأ أفضل ضمن فريق ؛ وتجنبوا from module import * التي تلوث فضاء الأسماء وتخفي التعارضات.
ما فائدة « if __name__ == '__main__' » حقا ؟
تجعل الملف قابلا للتنفيذ وقابلا للاستيراد معا : الكود تحتها لا يشتغل إلا عند الإطلاق المباشر (python fichier.py)، لا عند الاستيراد. نضع فيها العرض أو نقطة الدخول — مستورَدا، لا تقدم الوحدة سوى دوال، دون أثر جانبي.
ماذا يحدث لكتلة if __name__ == "__main__" عند الاستيراد ؟