إذا كنت تتعلم الدوال في بايثون Functions لأول مرة، فالفكرة الأساسية بسيطة: بدل أن تكرر مجموعة أوامر كلما احتجتها، تضعها داخل دالة لها اسم، ثم تستدعي هذه الدالة عند الحاجة. بهذه الطريقة يصبح الكود أقصر، أوضح، وأسهل في التعديل.
في هذا الدرس الثالث عشر من سلسلة أساسيات بايثون سنتعلم كيفية تعريف الدوال باستخدام def، واستدعائها، وتمرير القيم إليها عبر Parameters وArguments، واستخدام القيم الافتراضية، مع أمثلة عملية مناسبة للمبتدئين.
سنركز هنا على أساسيات بناء الدالة واستخدامها. أما return والفرق بينها وبين print() فسنأخذهما بالتفصيل في الدرس التالي حتى لا نخلط أكثر من مفهوم في درس واحد. وفي نهاية الدرس ستستطيع إنشاء دوال بسيطة بنفسك واستخدامها لتنظيم برامجك.
{getToc} $title={محتوى المقال}
{alertInfo} الدالة Function هي مجموعة أوامر لها اسم، نكتبها مرة واحدة ثم نستدعيها كلما احتجنا تنفيذ المهمة نفسها.
قبل البدء، يفضّل أن تكون مرتاحًا مع الشروط في بايثون و الحلقات Loops. ويمكنك تجربة جميع الأمثلة مباشرة داخل محرر بايثون العرب.
ما هي الدوال Functions في بايثون؟
الدالة في بايثون هي جزء من البرنامج يُعطى اسمًا ويحتوي على أوامر تنفذ مهمة محددة. الفائدة الأساسية منها هي تنظيم الكود وإعادة استخدامه بدل نسخ الأوامر نفسها في أكثر من مكان.
مثلًا، إذا كنت تريد طباعة رسالة ترحيب عدة مرات، يمكنك كتابة:
print("Welcome to Python")
print("Welcome to Python")
print("Welcome to Python")
لكن الأفضل أن تضع المهمة داخل دالة، ثم تستدعيها كلما احتجتها.
كيف نعرّف دالة باستخدام def؟
نستخدم الكلمة المفتاحية def لإنشاء دالة جديدة. الشكل الأساسي يكون كالتالي:
def function_name():
pass
استخدمنا pass هنا لأن جسم الدالة لا يمكن أن يكون فارغًا تمامًا. وفي البرنامج الحقيقي نضع الأوامر التي نريد تنفيذها.
مثال بسيط:
def say_hello():
print("Hello Python")
say_hello()
الناتج:
Hello Python
{alertSuccess} تعريف الدالة باستخدام def لا ينفذ جسمها مباشرة. التنفيذ يحدث عندما تستدعي الدالة بكتابة اسمها متبوعًا بالأقواس.
ما الفرق بين تعريف الدالة واستدعائها؟
| الخطوة | المثال | ماذا يحدث؟ |
|---|---|---|
| تعريف الدالة | def greet(): |
تنشئ دالة جديدة وتحدد الأوامر التي تنتمي إليها. |
| استدعاء الدالة | greet() |
تطلب من بايثون تنفيذ جسم الدالة. |
أجزاء الدالة في بايثون
لنأخذ هذا المثال:
def greet():
print("Welcome")
def: تبدأ بها عملية تعريف الدالة.greet: اسم الدالة.(): مكان كتابة Parameters إذا كانت الدالة تحتاجها.:: النقطتان اللتان تنهيان سطر تعريف الدالة.- الأسطر المزاحة للداخل: جسم الدالة الذي يتم تنفيذه عند الاستدعاء.
{alertWarning} المسافة البادئة Indentation جزء من صياغة بايثون. أوامر جسم الدالة يجب أن تكون مزاحة للداخل، وغالبًا نستخدم 4 مسافات.
إذا كان موضوع المسافات البادئة غير واضح لديك، راجع شرح Indentation في بايثون.
لماذا نستخدم Functions؟
الدوال لا توجد فقط لتقليل عدد الأسطر، بل تساعدك على تقسيم البرنامج إلى مهام واضحة. من أهم فوائدها:
- إعادة استخدام نفس المنطق أكثر من مرة.
- تقليل تكرار الكود.
- تقسيم البرنامج إلى أجزاء صغيرة يسهل فهمها.
- تعديل سلوك معين من مكان واحد بدل تغييره في عدة أماكن.
- تسهيل اختبار أجزاء البرنامج لاحقًا.
مثال:
def print_line():
print("----------------")
print_line()
print("Student Report")
print_line()
إذا أردت تغيير شكل الخط لاحقًا، ستعدل الدالة مرة واحدة فقط.
ما هي Parameters في الدوال؟
الـParameter هو اسم متغير تضعه داخل تعريف الدالة حتى تستقبل الدالة قيمة مختلفة عند كل استدعاء.
def greet(name):
print(f"Hello {name}")
greet("Ahmed")
greet("Sara")
الناتج:
Hello Ahmed
Hello Sara
الفرق بين Parameter وArgument
| المصطلح | معناه | مثال |
|---|---|---|
| Parameter | الاسم الموجود في تعريف الدالة. | def greet(name): |
| Argument | القيمة التي تمررها للدالة عند استدعائها. | greet("Ahmed") |
{alertInfo} باختصار: Parameter يظهر عند تعريف الدالة، وArgument هو القيمة الفعلية التي ترسلها عند الاستدعاء.
دالة تستقبل أكثر من Parameter
يمكن للدالة استقبال أكثر من قيمة. نفصل بين الـParameters بفاصلة:
def student_info(name, age):
print(f"Name: {name}")
print(f"Age: {age}")
student_info("Ali", 20)
الناتج:
Name: Ali
Age: 20
تمرير Arguments بالترتيب أو بالاسم
في المثال السابق مررنا القيم حسب ترتيب الـParameters. هذا يسمى غالبًا Positional Arguments:
student_info("Ali", 20)
ويمكنك أيضًا تمريرها باسم الـParameter، وهذا يجعل المعنى أوضح في بعض الحالات:
student_info(age=20, name="Ali")
عند استخدام الأسماء، لا تحتاج إلى الالتزام بترتيب الـParameters نفسه.
القيم الافتراضية Default Parameters
يمكنك إعطاء Parameter قيمة افتراضية تستخدمها الدالة إذا لم ترسل قيمة عند الاستدعاء:
def greet(name="Guest"):
print(f"Hello {name}")
greet()
greet("Mona")
الناتج:
Hello Guest
Hello Mona
هذه الفكرة مفيدة، لكن هناك نقطة متقدمة مهمة: لا تستخدم قائمة أو قاموسًا قابلًا للتعديل كقيمة افتراضية بدون فهم سلوكها، لأن ذلك قد يؤدي إلى مشكلة Mutable Default Arguments. لدينا شرح مستقل لها: حل مشكلة Mutable Default Arguments في بايثون.
تمهيد سريع إلى return
حتى الآن استخدمنا print() داخل الدوال لعرض النتائج. لكن الدوال تستطيع أيضًا إرجاع قيمة إلى بقية البرنامج باستخدام return.
def add(a, b):
return a + b
result = add(5, 3)
print(result)
الناتج:
8
لن نتوسع في return هنا؛ لأن الدرس التالي مخصص لها بالكامل:
أساسيات بايثون 14: شرح return في Functions والفرق بينها وبين print.
مثال عملي: دالة لفحص العدد الزوجي
يمكننا جمع ما تعلمناه عن Parameters والشروط داخل دالة واحدة:
def is_even(number):
return number % 2 == 0
print(is_even(10))
print(is_even(7))
الناتج:
True
False
ولفهم شرط الزوجي والفردي نفسه خطوة بخطوة، راجع معرفة هل العدد زوجي أم فردي في بايثون.
مثال عملي: دالة لحساب عدد الكلمات
هذا مثال آخر يوضح كيف نحول منطقًا صغيرًا إلى دالة قابلة لإعادة الاستخدام:
def count_words(text):
return len(text.split())
sentence = "I love Python programming"
print(count_words(sentence))
الناتج:
4
إذا أردت فهم فكرة حساب الكلمات قبل وضعها داخل دالة، راجع حساب عدد الكلمات في نص باستخدام بايثون.
كيف تختار اسمًا جيدًا للدالة؟
اجعل الاسم يصف المهمة التي تنفذها الدالة. في بايثون يُستخدم عادة أسلوب الكلمات الصغيرة المفصولة بشرطة سفلية snake_case.
calculate_total()
check_password()
print_report()
count_words()
الأسماء مثل x() أو abc() لا تشرح وظيفة الدالة، لذلك تجنبها إلا في حالات محدودة جدًا.
أخطاء شائعة عند استخدام Functions
1. تعريف الدالة ثم نسيان استدعائها
إذا كتبت تعريف الدالة فقط فلن ينفذ جسمها. بعد التعريف، استدعها عند الحاجة:
def hello():
print("Hello")
hello()
2. نسيان النقطتين أو المسافة البادئة
سطر def ينتهي بـ:، وجسم الدالة يجب أن يكون مزاحًا للداخل. إذا أهملت أحدهما سيظهر خطأ في الصياغة أو المسافة البادئة.
3. تمرير عدد Arguments لا يطابق المطلوب
إذا كانت الدالة تحتاج Parameter إلزاميًا، يجب أن تمرر له قيمة:
def greet(name):
print(f"Hello {name}")
greet("Ahmed")
4. الخلط بين Parameter وArgument
تذكر القاعدة البسيطة: الـParameter اسم داخل تعريف الدالة، أما الـArgument فهي القيمة التي ترسلها عند الاستدعاء.
متى أنشئ Function بدل كتابة الكود مباشرة؟
- عندما تتكرر المهمة نفسها في أكثر من مكان.
- عندما تستطيع إعطاء جزء من البرنامج اسمًا واضحًا يمثل مهمة واحدة.
- عندما تريد استخدام نفس المنطق مع بيانات مختلفة.
- عندما يبدأ البرنامج في الكبر وتحتاج إلى تقسيمه لأجزاء أصغر.
{alertSuccess} لا تنشئ دالة فقط لأنك تستطيع ذلك. أنشئها عندما تجعل الكود أوضح أو تقلل التكرار أو تفصل مهمة مستقلة عن بقية البرنامج.
أسئلة شائعة عن الدوال في بايثون
هل يمكن إنشاء دالة بدون Parameters؟
نعم. مثل say_hello()، ويمكن أن تحتوي الدالة على Parameters فقط عندما تحتاج إلى استقبال بيانات من الخارج.
هل يمكن للدالة استقبال أكثر من Argument؟
نعم. يمكنك تعريف أكثر من Parameter داخل الأقواس والفصل بينها بفواصل، ثم تمرير القيم المناسبة عند الاستدعاء.
هل يجب أن تحتوي كل دالة على return؟
لا. يمكن للدالة تنفيذ أوامر بدون كتابة return. وسنشرح سلوك return بالتفصيل في الدرس التالي من السلسلة.
ما الفرق بين الدالة الجاهزة والدالة التي أكتبها؟
بايثون توفر دوال جاهزة مثل print() وlen(). أما الدالة التي تنشئها باستخدام def فهي User-defined Function تكتبها أنت لتنفيذ المهمة التي يحتاجها برنامجك.
روابط مفيدة من بايثون العرب
- كورس أساسيات بايثون للمبتدئين
- الدرس السابق: الحلقات Loops في بايثون
- الدرس التالي: return في Functions والفرق بينها وبين print
- مثال عملي: حساب عدد الكلمات في نص
- توثيق بايثون الرسمي لتعريف الدوال
خلاصة الدرس
الدوال في بايثون تساعدك على تنظيم البرنامج وإعادة استخدام المنطق بدل تكراره. تبدأ الدالة بالكلمة def، ثم اسم الدالة، ثم Parameters إن وجدت، وبعدها جسم الدالة بمسافة بادئة.
تعلمنا أيضًا الفرق بين Parameter وArgument، وكيف تمرر أكثر من قيمة، وتستخدم القيم الافتراضية، وتستدعي الدالة في أكثر من مكان. أما إعادة القيم باستخدام return فسنفصلها في الدرس التالي.
{alertSuccess} الخلاصة السريعة: عرّف المهمة باستخدام def، مرّر البيانات عبر Parameters، ثم استدعِ الدالة كلما احتجت تنفيذ المهمة نفسها.
تمرين بسيط لك
اكتب دالة اسمها rectangle_area تستقبل width وheight، ثم تعيد مساحة المستطيل. بعد ذلك اطبع نتيجة استدعائها بالقيم 5 و4.
النتيجة المتوقعة:
20



