• أهمية الدرس: تساعدك الدوال على تحويل البرنامج من أسطر متتابعة يصعب تتبعها إلى مهام صغيرة واضحة، لكل مهمة اسم يمكن استدعاؤه كلما احتجت إليه.
  • ماذا ستتعلم:
    • لماذا نستخدم الدوال بدل تكرار الكود؟
    • كيف نعرّف دالة ثم نستدعيها؟
    • كيف تستقبل الدالة بيانات مختلفة؟
    • متى نستخدم return، وما الفرق بينها وبين print؟
    • كيف نبني دالة واضحة يسهل فهمها وإعادة استخدامها؟

 


 

لماذا نضع الكود داخل دالة؟

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

  • إعادة الاستخدام: بدل كتابة حساب مساحة المستطيل في عدة مواضع، نضع الحساب في دالة واحدة ونستدعيها عند الحاجة.
  • وضوح البرنامج: اسم مثل calculate_area يوضح المقصود أسرع من قراءة تفاصيل الحساب في كل مرة.
  • سهولة التعديل: إذا تغيرت طريقة تنفيذ المهمة، نعدّل الدالة في مكان واحد بدل البحث عن نسخ متكررة من الكود.
  • تقسيم المشكلة: يمكن تقسيم البرنامج الكبير إلى مهام صغيرة، مثل قراءة البيانات، وحساب النتيجة، وعرضها.

الفكرة ليست أن نجعل كل سطر دالة مستقلة؛ بل أن نجمع الأسطر التي تؤدي مهمة واضحة قابلة للتسمية. وهذا يحقق مبدأ «لا تكرر نفسك».


تعريف الدالة ليس هو استدعاءها

عند تعريف دالة، نحن نخبر بايثون بخطوات المهمة ونمنحها اسمًا. أما التنفيذ الفعلي فلا يبدأ إلا عندما نستدعي الدالة.

def say_hello():
    print("مرحبًا بعالم الدوال")

print("قبل الاستدعاء")
say_hello()
print("بعد الاستدعاء")
  • تبدأ صيغة التعريف بالكلمة def، ثم اسم الدالة والأقواس، وتنتهي بنقطتين رأسيتين.
  • جسم الدالة هو الأسطر المزاحة إلى الداخل. هذه الإزاحة جزء من صياغة بايثون وليست للزينة.
  • say_hello() هو الاستدعاء؛ لذلك ينفذ الجسم بين عبارتي «قبل الاستدعاء» و«بعد الاستدعاء».
  • يمكن استدعاء الدالة أكثر من مرة، وفي كل استدعاء تنفَّذ خطواتها من البداية.

اختر اسمًا يصف الفعل، مثل show_menu أو calculate_total، واستخدم أسلوب snake_case عند تكوين الاسم من أكثر من كلمة.


المعاملات تجعل الدالة مرنة

الدالة التي تطبع اسمًا ثابتًا فائدتها محدودة. ولجعلها تعمل مع أسماء مختلفة، نضع داخل أقواس التعريف معاملًا يستقبل القيمة وقت الاستدعاء.

def greet_user(name):
    print(f"أهلًا، {name}!")

greet_user("سلمى")
greet_user("علي")
  • المعامل parameter هو الاسم الموجود في تعريف الدالة؛ ويمثل مكانًا لقيمة ستصل لاحقًا. في المثال، name هو المعامل.
  • الوسيط argument هو القيمة الفعلية التي نرسلها عند الاستدعاء، مثل "سلمى".
  • يمكن للدالة استقبال أكثر من معامل. في calculate_area(width, height) يجب أن يزوّدها الاستدعاء بقيمتي العرض والارتفاع.
  • كل استدعاء مستقل: تتغير القيم التي تعمل عليها الدالة، بينما تبقى خطواتها نفسها.

فكّر في المعامل كخانة تحمل اسمًا، وفي الوسيط كالقيمة التي نضعها في تلك الخانة عند الاستخدام.


print تعرض، وreturn تعيد

هذا الفرق مهم: عرض نتيجة للمستخدم ليس هو تسليم النتيجة إلى بقية البرنامج.

الأداة ماذا تفعل؟ متى تفيد؟
print تعرض نصًا أو قيمة على الشاشة. عند إرسال رسالة إلى المستخدم.
return تعيد قيمة إلى موضع استدعاء الدالة. عند تخزين النتيجة أو استخدامها في حساب آخر.
def square(number):
    return number * number

answer = square(6)
print(answer + 4)

أعادت الدالة القيمة 36، فخزنها البرنامج في answer ثم استخدمها في عملية جديدة. وعندما تنفذ بايثون return تنتهي الدالة فورًا؛ لذلك لا تنفذ الأسطر التي تأتي بعدها داخل الجسم. وإذا انتهت دالة بلا return، فقيمتها المعادة هي None، حتى لو كانت قد طبعت شيئًا على الشاشة.


صمّم الدالة حول مهمة واحدة واضحة

الدالة الجيدة لا تُقاس بعدد أسطرها فقط، بل بوضوح مسؤوليتها. عندما تستطيع وصف عملها بجملة قصيرة، يصبح اسمها واختبارها وإعادة استخدامها أسهل.

  • استخدم اسمًا دالًا: calculate_rectangle_area أوضح من do_it.
  • اجعل لكل دالة مهمة محددة؛ فدالة الحساب تحسب، ويمكن لجزء آخر من البرنامج أن يقرأ الإدخال أو يعرض النتيجة.
  • لا تعتمد داخل الدالة على أرقام ثابتة إذا كانت القيم تتغير؛ مرّرها في صورة معاملات.
  • اكتب نصًا توثيقيًا docstring في بداية الجسم عندما تحتاج إلى توضيح الغرض والمدخلات والقيمة المعادة.
def calculate_rectangle_area(width, height):
    """تعيد مساحة مستطيل من عرضه وارتفاعه."""
    return width * height

بهذا التصميم لا تعرف الدالة من أين جاءت القيم، ولا كيف ستُعرض النتيجة؛ هي تعرف مهمتها فقط: حساب المساحة وإعادتها.


من المدخلات إلى النتيجة: اجمع الأجزاء بترتيب واضح

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

def calculate_rectangle_area(width, height):
    return width * height

user_width = float(input("أدخل العرض: "))
user_height = float(input("أدخل الارتفاع: "))

area = calculate_rectangle_area(user_width, user_height)
print(f"مساحة المستطيل هي: {area}")
  • input تقرأ القيم في صورة نصوص، ولذلك يحولها float إلى أعداد.
  • القيمتان user_width وuser_height هما وسيطان عند الاستدعاء.
  • تصل القيمتان داخل الدالة إلى المعاملين width وheight.
  • تعيد الدالة المساحة، ثم تُخزّن في area قبل عرضها.

تتبّع هذا المسار دائمًا عند قراءة كود الدوال: ما القيم المرسلة؟ ماذا تنفذ الدالة؟ ما القيمة المعادة؟ وأين استُخدمت؟ بهذه الأسئلة يصبح تتبع الاستدعاءات أسهل بكثير.


التمارين المرتبطة بهذا الدرس

  • التمرين الأول: بناء الدوال وإعادة استخدامها
  • التمرين الثاني: تتبع الاستدعاءات والقيم المعادة
  • التمرين الثالث: إكمال تعريفات الدوال
المزيد من المحتوى؟

سجل للوصول إلى المزيد