الوحدات والحزم في بايثون: صناديق أدوات جاهزة لبرامجك

تعلّم استيراد الوحدات في بايثون بـ import و from و as، واستكشافها بـ dir()، وكيف تصنع وحدتك وحزمتك الخاصة.

تريد أن تحسب الجذر التربيعي لرقم، أو تختار سؤالًا عشوائيًا في لعبة مسابقات. هل تكتب كل ذلك من الصفر؟ لا. بايثون تأتي مع مئات الأدوات الجاهزة، وكل ما تحتاجه هو أن تعرف كيف “تستعيرها”. في هذا الدرس ستتعلّم كيف تفعل ذلك، وكيف تصنع أدواتك أنت أيضًا.

🎯 ماذا ستتعلم؟

بنهاية هذا الدرس ستكون قادرًا على:

  • استيراد وحدة جاهزة من بايثون واستخدام دوالها.
  • التفريق بين import و from ... import و as.
  • استكشاف ما بداخل أي وحدة باستخدام dir().
  • فهم كيف تصنع وحدتك الخاصة في ملف منفصل.
  • معرفة ما هي الحزمة وكيف تُنظّم الوحدات.

🧰 ماذا تحتاج قبل أن تبدأ؟

يجب أن تعرف كيف تكتب دالة وتستدعيها. إن لم تكن متأكدًا، اقرأ أولًا الدوال في بايثون. ويفيدك أيضًا أن تعرف المتغيّرات وأنواع البيانات. كل الأمثلة تعمل في مترجم بايثون في المتصفح بدون تثبيت.

الفكرة ببساطة

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

الوحدة (module) في بايثون هي صندوق أدوات كهذا. هي ملف بايثون فيه دوال ومتغيّرات جاهزة. وعندما تكتب import فأنت تقول: “افتح لي هذا الصندوق”.

وإذا كثرت الصناديق، تجمعها في خزانة واحدة مرتّبة. هذه الخزانة هي الحزمة (package). سنبدأ بالصناديق الجاهزة التي تأتي مع بايثون، ثم نصنع صندوقنا الخاص.

الخطوة 1: استيراد وحدة بـ import

الوحدة math تحتوي على أدوات رياضية. لاستخدامها، اكتب import math في أول البرنامج. بعد ذلك تصل إلى أي أداة فيها بكتابة اسم الوحدة، ثم نقطة، ثم اسم الأداة.

import math
# الجذر التربيعي لمساحة ملعب مربّع
side = math.sqrt(144)
print("طول ضلع الملعب:", side)
print("قيمة باي:", math.pi)
طول ضلع الملعب: 12.0
قيمة باي: 3.141592653589793

النقطة في math.sqrt تعني: “من داخل صندوق math، أعطني الأداة sqrt”. و math.pi ليس دالة، بل متغيّر جاهز فيه قيمة باي. الوحدة يمكن أن تحتوي على دوال ومتغيّرات معًا.

هنا مثال آخر من الوحدة نفسها. الدالة math.ceil() تقرّب الرقم إلى الأعلى، و math.floor() تقرّبه إلى الأسفل:

import math
# معدل الطالب هو 87.3، كم يصير لو قرّبناه؟
average = 87.3
print("إلى الأعلى:", math.ceil(average))
print("إلى الأسفل:", math.floor(average))
إلى الأعلى: 88
إلى الأسفل: 87

الخطوة 2: استيراد أداة واحدة بـ from

أحيانًا لا تحتاج الصندوق كله، بل أداة واحدة منه. عندها اكتب from math import sqrt. الآن تستدعي sqrt() مباشرة بدون كتابة math. قبلها.

from math import sqrt
# نحسب طول قطر شاشة عرضها 16 وارتفاعها 12
diagonal = sqrt(16 * 16 + 12 * 12)
print("طول القطر:", diagonal)
طول القطر: 20.0

ويمكنك استيراد أكثر من أداة في سطر واحد، تفصل بينها بفاصلة:

from math import sqrt, pi
print(sqrt(81))
print(pi)
9.0
3.141592653589793

🚀 للمتقدمين: يوجد شكل ثالث هو from math import *. النجمة تعني “أحضر كل شيء”. لكنّه غير محبّب، لأنك لا تعرف ما الأسماء التي دخلت برنامجك. وقد تحلّ إحداها مكان متغيّر كتبته أنت باسم مشابه. الأفضل أن تستورد ما تحتاجه بالاسم.

الخطوة 3: اسم مختصر بـ as

بعض الوحدات أسماؤها طويلة، وتكتبها عشرات المرات. الكلمة as تعطي الوحدة اسمًا مستعارًا قصيرًا. هنا نستورد الوحدة random، التي تختار أشياء عشوائية، ونسمّيها rd:

import random as rd
questions = ["ما عاصمة مصر؟", "كم عدد الكواكب؟", "ما أكبر محيط؟"]
# نختار سؤالًا عشوائيًا للمسابقة
chosen = rd.choice(questions)
print("هل السؤال من القائمة؟", chosen in questions)
print("عدد الأسئلة:", len(questions))
هل السؤال من القائمة؟ True
عدد الأسئلة: 3

لاحظ أننا لم نطبع السؤال نفسه. لأنه عشوائي، سيختلف في كل تشغيل. لذلك طبعنا سؤالًا آخر: هل السؤال المختار موجود في القائمة؟ والجواب دائمًا True. جرّب أن تطبع chosen بنفسك وشغّل الكود عدة مرات.

الخطوة 4: ماذا يوجد داخل الصندوق؟

كيف تعرف الأدوات الموجودة في وحدة لم تستخدمها من قبل؟ الدالة dir() تعطيك قائمة بكل الأسماء الموجودة فيها. القائمة طويلة، لذلك سنسأل عن أدوات معيّنة فقط:

import math
tools = dir(math)
print("هل فيها sqrt؟", "sqrt" in tools)
print("هل فيها pi؟", "pi" in tools)
print("هل فيها football؟", "football" in tools)
هل فيها sqrt؟ True
هل فيها pi؟ True
هل فيها football؟ False

وهناك دالة أخرى مفيدة هي help(). اكتب help(math.sqrt) في المترجم، وسيظهر لك شرح مكتوب عن الدالة. جرّبها بنفسك، فهي طريقة رائعة لتتعلّم أدوات جديدة.

الخطوة 5: اصنع وحدتك الخاصة

الوحدة هي ملف بايثون عادي. إذا كتبت دوالك في ملف اسمه tools.py، فقد صنعت وحدة اسمها tools. ويمكن لأي ملف آخر في المجلد نفسه أن يستوردها.

هذا المثال يحتاج ملفين، لذلك لا يعمل في مترجم المتصفح. جرّبه على جهازك إذا كان بايثون مثبّتًا عندك:

📁 my_game/
   ├── tools.py
   └── main.py

الملف الأول هو الوحدة، وفيه دالة تحسب النقاط:

# tools.py
def calc_score(correct, wrong):
    return correct * 10 - wrong * 5

والملف الثاني هو البرنامج الرئيسي، وهو يستورد الوحدة ويستخدمها:

# main.py
import tools

score = tools.calc_score(8, 2)
print("نقاطك:", score)

عند تشغيل main.py يبحث بايثون عن ملف اسمه tools.py في المجلد نفسه. يجده، ويقرأ الدوال فيه، ثم يكمل البرنامج ويطبع نقاطك: 70.

الحزمة (package) هي مجلد يجمع عدة وحدات معًا. لتخبر بايثون أن المجلد حزمة، ضع فيه ملفًا فارغًا اسمه __init__.py:

📁 school/
   ├── __init__.py
   ├── grades.py
   └── timetable.py

ثم تستورد وحدة من الحزمة بالنقطة أيضًا: from school import grades. وهكذا تصير النقطة تعني دائمًا “ادخل إلى”.

🚀 للمتقدمين: عندما يستورد بايثون وحدة، فإنه ينفّذ الملف مرة واحدة فقط. لو استوردتها في عشرة أماكن، تُحمَّل مرة واحدة. ويبحث بايثون عن الوحدات في قائمة مجلدات اسمها sys.path. يمكنك إضافة مجلد إليها بـ sys.path.append("مسار/المجلد") قبل سطر import. وفي الإصدارات الحديثة يعمل المجلد كحزمة حتى بدون __init__.py، لكن وجوده يبقى العادة الأوضح.

⚠️ أخطاء شائعة

الأخطاء طبيعية جدًا في البداية، وكل مبرمج مرّ بها. إليك ثلاثة تقابلها كثيرًا مع الوحدات:

1. استخدام الأداة بدون استيراد

❌
print(math.sqrt(25))
NameError: name 'math' is not defined

بايثون لا يعرف math حتى تفتح الصندوق. ضع سطر الاستيراد أولًا:

# ✅
import math
print(math.sqrt(25))
5.0

2. نسيان اسم الوحدة قبل النقطة

❌
import math
print(sqrt(25))
NameError: name 'sqrt' is not defined

مع import math يجب أن تكتب math.sqrt. أو استورد الدالة نفسها بـ from:

# ✅
from math import sqrt
print(sqrt(25))
5.0

3. تسمية ملفك باسم وحدة موجودة

إذا سمّيت ملفك random.py ثم كتبت فيه import random، سيستورد بايثون ملفك أنت لا الوحدة الحقيقية. وستظهر أخطاء غريبة مثل:

❌
AttributeError: module 'random' has no attribute 'choice'

الحل بسيط: اختر لملفاتك أسماء خاصة بك، مثل my_quiz.py:

# ✅
import random
numbers = [1, 2, 3, 4, 5, 6]
dice = random.choice(numbers)
print("هل الرقم بين 1 و 6؟", 1 <= dice <= 6)
هل الرقم بين 1 و 6؟ True

🧪 جرّب بنفسك

التحدي 1: مساحة الدائرة

استورد pi من الوحدة math، واحسب مساحة دائرة نصف قطرها 3. المساحة تساوي باي مضروبة في نصف القطر مرّتين. قرّب النتيجة بـ round().

# استورد pi ثم احسب المساحة
radius = 3
print(radius)
3
💡 اضغط لرؤية الحل
from math import pi
radius = 3
area = pi * radius * radius
print("المساحة:", round(area))
المساحة: 28

التحدي 2: حروف الأبجدية

الوحدة string فيها متغيّر اسمه ascii_lowercase يحتوي على الحروف الإنجليزية الصغيرة. استورد الوحدة باسم مستعار s، واطبع عدد الحروف، ثم اطبع أول ثلاثة حروف.

# استورد string باسم s
print("ابدأ هنا")
ابدأ هنا
💡 اضغط لرؤية الحل
import string as s
letters = s.ascii_lowercase
print("عدد الحروف:", len(letters))
print("أول ثلاثة:", letters[0:3])
عدد الحروف: 26
أول ثلاثة: abc

التحدي 3: خلط الفريق

عندك قائمة بخمسة لاعبين. استورد random، واستخدم random.shuffle() لخلط ترتيبهم. ثم تأكّد أن عدد اللاعبين لم يتغيّر، وأن اللاعب “سالم” ما زال موجودًا.

players = ["سالم", "نورة", "خالد", "ليلى", "عمر"]
# اخلط القائمة ثم تحقّق
print(len(players))
5
💡 اضغط لرؤية الحل
import random
players = ["سالم", "نورة", "خالد", "ليلى", "عمر"]
random.shuffle(players)
print("عدد اللاعبين:", len(players))
print("هل سالم موجود؟", "سالم" in players)
عدد اللاعبين: 5
هل سالم موجود؟ True

الترتيب يختلف في كل تشغيل، لكن العدد والأسماء لا تتغيّر. اطبع players لترى الخلط بنفسك.

✅ اختبر نفسك

  1. ماذا يكتب في أول البرنامج لاستخدام math.sqrt()؟

    • أ) from sqrt import math
    • ب) import math
    • ج) open math
  2. بعد from math import pi، كيف تطبع قيمة باي؟

    • أ) print(pi)
    • ب) print(math.pi)
    • ج) print(pi.math)
  3. صح أم خطأ: الوحدة في بايثون هي مجرد ملف بايثون عادي.

💡 اضغط لرؤية الإجابات
  1. ب) import math، ثم تصل إلى الدالة بكتابة math.sqrt().
  2. أ) print(pi)، لأن from أحضرت الاسم مباشرة إلى برنامجك بدون math. قبله.
  3. صح. أي ملف ينتهي بـ .py يمكن استيراده كوحدة.

📝 الخلاصة

  • الوحدة ملف بايثون فيه دوال ومتغيّرات جاهزة، والحزمة مجلد يجمع عدة وحدات.
  • import math يفتح الصندوق كله، وتصل إلى أدواته بالنقطة: math.sqrt().
  • from math import sqrt يحضر أداة واحدة، فتستخدمها مباشرة بدون اسم الوحدة.
  • as يعطي الوحدة اسمًا مستعارًا قصيرًا.
  • dir() تكشف لك الأسماء الموجودة في أي وحدة، و help() تشرحها.

⏭️ الخطوة التالية

صرت الآن تعرف كيف تستعير أدوات بايثون الجاهزة. افتح مترجم بايثون وجرّب dir(random) و dir(string) واكتشف أدوات جديدة. وفي الدرس القادم ستتعلّم كيف يتحدّث برنامجك مع المستخدم في الإدخال والإخراج في بايثون.