أمثلة على دوال بايثون: كيفية تعريف الدوال واستدعائها باستخدام المعاملات
توفّر لغة Python مجموعة كبيرة من الدوال المدمجة التي تساعدك على تنفيذ مهام متنوعة بسرعة وكفاءة. لكن قوة اللغة لا تتوقف عند هذا الحد، إذ تتيح لك أيضاً إنشاء دوالك الخاصة لتجميع الأوامر المتكررة وتنظيم الشيفرة بشكل أفضل.
في هذا الدليل العملي، ستتعرف على معنى الدالة في Python، وكيفية تعريفها واستدعائها، وطريقة تمرير المعاملات والوسائط إليها، مع توضيح الفرق بين الوسائط الموضعية positional arguments، والوسائط المسماة keyword arguments، والوسائط الافتراضية default arguments.

ما هي الدالة في بايثون؟
الدالة هي كتلة مستقلة من الشيفرة البرمجية تُنفّذ مهمة محددة. استخدام الدوال يجعل البرنامج أكثر ترتيباً وأسهل في الصيانة، لأنك تكتب المنطق مرة واحدة ثم تعيد استخدامه متى احتجت إليه.
تكمن أهمية الدوال في عدة نقاط:
- تقليل التكرار غير الضروري في الشيفرة.
- تسهيل إعادة الاستخدام في أكثر من موضع داخل البرنامج.
- تحسين قابلية القراءة والفهم.
- تسهيل التعديل لاحقاً، لأنك تغيّر الشيفرة في مكان واحد فقط.
هذا الأسلوب ينسجم مع مبدأ DRY، وهو اختصار لعبارة Don't Repeat Yourself، أي تجنّب تكرار الشيفرة ما أمكن.
ومن المهم معرفة أن الشيفرة داخل الدالة لا تُنفَّذ إلا عند استدعاء الدالة. كما يمكن للدالة أن تستقبل مدخلات، وقد تُرجع قيمة باستخدام return أو قد تعمل دون إرجاع أي قيمة.
كيفية تعريف دالة في Python
الصيغة العامة لتعريف دالة في Python تكون كالتالي:
def function_name(parameters):
function body
شرح مكوّنات تعريف الدالة
def: كلمة محجوزة تُخبرPythonأنك بصدد تعريف دالة جديدة.function_name: اسم الدالة، ويجب أن يكون اسماً صالحاً.(): الأقواس التي قد تحتوي على صفر أو أكثر من المعاملاتparameters.:: النقطتان الرأسيتان اللتان تُنهيان سطر التعريف.- المسافة البادئة
indentation: ضرورية لتحديد الشيفرة التابعة للدالة. - جسم الدالة
function body: ويتضمن الأوامر التي ستُنفذ عند استدعاء الدالة. return: عبارة اختيارية لإرجاع قيمة إلى المكان الذي استدعى الدالة.
يُفضَّل أن تبدأ أسماء الدوال بحرف أو علامة _، ويمكن أن تتضمن أرقاماً، وغالباً ما تُكتب الكلمات بحروف صغيرة ويفصل بينها بشرطة سفلية مثل my_function.
إذا نسيت كتابة الأقواس () أو النقطتين : أثناء تعريف الدالة، فستحصل غالباً على خطأ من نوع SyntaxError.
إنشاء دالة بسيطة واستدعاؤها
لنبدأ بمثال مباشر على دالة لا تستقبل أي معاملات ولا تُرجع قيمة، بل تطبع فقط عبارة ترحيبية:
def hello_world_func():
print("hello world")
بعد تعريف الدالة، لن تُنفّذ الشيفرة تلقائياً. يجب استدعاء الدالة صراحةً حتى تعمل:
function_name(arguments)
أي أنك تكتب اسم الدالة متبوعاً بأقواس. وإذا لم تكن هناك أي وسائط، فستبقى الأقواس مطلوبة.
استدعاء الدالة السابقة يكون كالتالي:
hello_world_func()
# Output
# hello world
ما الفرق بين parameters و arguments؟
يخلط كثير من المبتدئين بين المصطلحين، لكن الفرق بسيط:
parameters: هي الأسماء التي تُكتب داخل تعريف الدالة، وتعمل كمتغيرات محلية تستقبل القيم.arguments: هي القيم الفعلية التي ترسلها عند استدعاء الدالة.
مثال:
def hello_to_you(name):
print("Hello " + name)
في هذا المثال، name هو parameter.
وعند الاستدعاء:
hello_to_you("Timmy")
فإن "Timmy" هي argument تم تمريرها إلى المعامل name.
تعريف دوال تستقبل معاملات في بايثون
يمكنك تمرير بيانات إلى الدالة لكي تعمل عليها بدلاً من الاكتفاء بطباعة نص ثابت. على سبيل المثال:
def hello_to_you(name):
print(f"Hello {name}")
هنا تستخدم الدالة تنسيق السلاسل من نوع f-string لعرض الاسم.
ويمكن أيضاً تمرير أكثر من معامل داخل الأقواس، مع الفصل بينها بفواصل:
def name_and_age(name, age):
print(f"I am {name} and I am {age} years old!")
في هذه الحالة، تحتوي الدالة على معاملين هما name وage.
استدعاء الدالة مع وسائط فعلية
def hello_to_you(name):
print(f"Hello {name}")
hello_to_you("Timmy")
# Output
# Hello Timmy
كما يمكنك استدعاء الدالة نفسها أكثر من مرة مع قيم مختلفة:
def hello_to_you(name):
print(f"Hello {name}")
hello_to_you("Timmy")
hello_to_you("Kristy")
hello_to_you("Jackie")
hello_to_you("Liv")
# Output
# Hello Timmy
# Hello Kristy
# Hello Jackie
# Hello Liv
الوسائط الموضعية Positional Arguments
الوسائط التي استخدمناها حتى الآن تُسمى وسائط موضعية positional arguments. في هذا النوع، يعتمد الربط بين القيم والمعاملات على ترتيبها داخل الاستدعاء.
عدد الوسائط يجب أن يكون مطابقاً
إذا كانت الدالة تتوقع معاملين، فيجب تمرير وسيطين بالضبط. لا أقل ولا أكثر.
def hello_to_you(first_name, last_name):
print(f"Hello, {first_name} {last_name}")
إذا مرّرت وسيطاً واحداً فقط:
def hello_to_you(first_name, last_name):
print(f"Hello, {first_name} {last_name}")
hello_to_you("Timmy")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: hello_to_you() missing 1 required positional argument: 'last_name'
وإذا مرّرت ثلاثة وسائط:
def hello_to_you(first_name, last_name):
print(f"Hello, {first_name} {last_name}")
hello_to_you("Timmy", "Jones", 34)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: hello_to_you() takes 2 positional arguments but 3 were given
أما إذا لم تمرّر أي وسيط:
def hello_to_you(first_name, last_name):
print(f"Hello, {first_name} {last_name}")
hello_to_you()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: hello_to_you() missing 2 required positional arguments: 'first_name' and 'last_name'
والاستدعاء الصحيح يكون هكذا:
def hello_to_you(first_name, last_name):
print(f"Hello, {first_name} {last_name}")
hello_to_you("Timmy", "Jones")
# Output
# Hello, Timmy Jones
ترتيب الوسائط الموضعية مهم جداً
في الوسائط الموضعية، لا يكفي أن تمرر العدد الصحيح فقط، بل يجب أيضاً الالتزام بالترتيب الصحيح. أول قيمة تُسند إلى أول معامل، والثانية إلى الثاني، وهكذا.
def hello_to_you(first_name, last_name):
print(f"Hello, {first_name} {last_name}")
hello_to_you("Timmy", "Jones")
# first_name = "Timmy"
# last_name = "Jones"
إذا تغيّر الترتيب، قد تحصل على نتيجة غير منطقية:
def fave_language(name, language):
print(f"Hello, I am {name} and my favorite programming language is {language}")
fave_language("Python", "Dionysia")
# Output
# Hello, I am Python and my favorite programming language is Dionysia
هنا تم إسناد "Python" إلى name، و"Dionysia" إلى language، لذلك ظهرت النتيجة بشكل غير مقصود.
الوسائط المسماة Keyword Arguments
في Python يمكنك استخدام نوع آخر من الوسائط يسمى الوسائط المسماة keyword arguments. بدلاً من تمرير القيم فقط، تكتب اسم المعامل ثم القيمة بالشكل key=value.
def fave_language(name, language):
print(f"Hello, I am {name} and my favorite programming language is {language}")
fave_language(name="Dionysia", language="Python")
# Output
# Hello, I am Dionysia and my favorite programming language is Python
ميزة هذا الأسلوب أنه أوضح في القراءة، ويقلل فرص الخطأ عند التعامل مع دوال تحتوي على عدة معاملات.
الترتيب هنا أكثر مرونة
عند استخدام الوسائط المسماة، لا يعود الترتيب مهماً ما دمت قد حدّدت اسم كل معامل بوضوح:
def fave_language(name, language):
print(f"Hello, I am {name} and my favorite programming language is {language}")
fave_language(language="Python", name="Dionysia")
# Output
# Hello, I am Dionysia and my favorite programming language is Python
لكن رغم أن الترتيب لا يهم، فإن عدد القيم المطلوبة يظل مهماً، لأن كل معامل مطلوب يحتاج إلى قيمة مناسبة.
الجمع بين الوسائط الموضعية والمسماة
يمكنك المزج بين النوعين في الاستدعاء نفسه:
def fave_language(name, language):
print(f"Hello, I am {name} and my favorite programming language is {language}")
fave_language("dionysia", language="Python")
# Output
# Hello, I am dionysia and my favorite programming language is Python
لكن توجد قاعدة مهمة: يجب أن تأتي الوسائط الموضعية أولاً، ثم تليها الوسائط المسماة. إذا عكست هذا الترتيب فسيظهر خطأ.
def fave_language(name, language):
print(f"Hello, I am {name} and my favorite programming language is {language}")
fave_language(language="Python", "dionysia")
الوسائط الافتراضية Default Arguments
يمكنك جعل بعض معاملات الدالة اختيارية عبر إسناد قيم افتراضية لها داخل التعريف. تُسمى هذه القيم بالوسائط الافتراضية أو الاختيارية.
def fave_language(language="python"):
print(f"My favorite programming language is {language}!")
fave_language()
# Output
# My favorite programming language is python!
في هذا المثال، إذا لم تُمرّر قيمة للمعامل language، فستستخدم الدالة القيمة الافتراضية "python".
تجاوز القيمة الافتراضية
يمكنك استبدال القيمة الافتراضية بسهولة عند الاستدعاء:
def fave_language(language="python"):
print(f"My favorite programming language is {language}!")
fave_language("Java")
# Prints: My favorite programming language is Java!
استخدام أكثر من قيمة افتراضية
لا يوجد ما يمنع من تعريف أكثر من معامل افتراضي داخل الدالة نفسها:
def personal_details(name="Jimmy", age=28, city="Berlin"):
print(f"I am {name}, {age} years old and live in {city}")
personal_details()
# Output:
# I am Jimmy, 28 years old and live in Berlin
personal_details(age=30)
# Output:
# I am Jimmy, 30 years old and live in Berlin
personal_details(city="Athens", name="Ben", age=24)
# Output:
# I am Ben, 24 years old and live in Athens
هذا يمنحك مرونة كبيرة، إذ يمكنك تمرير جميع القيم أو بعضها أو عدم تمرير أي منها، حسب الحاجة.
دمج الوسائط الإلزامية والافتراضية
من الشائع جداً أن تحتوي الدالة على معاملات إلزامية وأخرى اختيارية في الوقت نفسه:
def fave_language(name, language="Python"):
print(f"My name is {name} and my favorite programming language is {language}!")
fave_language("Dionysia")
# Output
# My name is Dionysia and my favorite programming language is Python!
في هذا المثال:
nameمعامل إلزامي.language="Python"معامل اختياري له قيمة افتراضية.
إذا لم تُمرّر قيمة للمعامل language، فستُستخدم القيمة الافتراضية تلقائياً.
ترتيب تعريف المعاملات مهم
عند الجمع بين المعاملات الإلزامية والافتراضية داخل تعريف الدالة، يجب أن تأتي المعاملات الإلزامية أولاً، ثم المعاملات ذات القيم الافتراضية.
هذا التعريف غير صحيح:
def fave_language(language="Python", name):
print(f"My name is {name} and my favorite programming language is {language}!")
fave_language("Dionysia")
وسينتج عنه الخطأ التالي:
File "<stdin>", line 1
SyntaxError: non-default argument follows default argument
والسبب أن Python لا تسمح بوجود معامل غير افتراضي بعد معامل افتراضي داخل تعريف الدالة.
أفضل ممارسات عند كتابة دوال بايثون
- اختر أسماء واضحة للدوال تعبّر عن وظيفتها بدقة.
- اجعل كل دالة مسؤولة عن مهمة واحدة فقط قدر الإمكان.
- استخدم الوسائط المسماة عندما تكون الدالة تحتوي على عدة معاملات لتوضيح المقصود.
- لا تفرط في استخدام القيم الافتراضية إلا عندما تكون مفيدة فعلاً.
- اختبر عدد الوسائط وترتيبها جيداً لتجنّب أخطاء
TypeErrorوSyntaxError.
ملخص سريع لأنواع الوسائط في دوال Python
| النوع | الوصف | هل الترتيب مهم؟ | هل يمكن تجاهله؟ |
|---|---|---|---|
الوسائط الموضعية Positional |
تُمرَّر حسب موقعها داخل الاستدعاء | نعم | لا |
الوسائط المسماة Keyword |
تُمرَّر بصيغة key=value |
لا | لا، إذا كانت مطلوبة |
الوسائط الافتراضية Default |
لها قيم مسبقة داخل تعريف الدالة | غالباً لا عند التسمية | نعم |
الخلاصة التقنية
إتقان الدوال في Python ليس مجرد خطوة أساسية للمبتدئين، بل هو حجر أساس لبناء برامج قابلة للتطوير والصيانة. كلما فهمت الفرق بين parameters وarguments، وأحسنت استخدام الوسائط الموضعية والمسماة والافتراضية، أصبحت شيفرتك أوضح وأكثر مرونة. من الناحية العملية، يُنصح باستخدام الدوال لتقسيم المشكلات الكبيرة إلى أجزاء صغيرة ومنطقية، لأن ذلك يحسن جودة الكود ويقلل الأخطاء على المدى الطويل.