تعدُّ المعاملات في تعاريف الدوال كيانات مسماة تُحدِّد وسيطًا (argument) يمكن أن يُمرَّر إلى الدالة المُعرَّفة.
أثناء البرمجة، قد لا تدرك جميع حالات الاستخدام الممكنة للشيفرة، لذا قد ترغب في توسيع خيارات المبرمجين المستقبليين الذين سيستخدمون الوحدة التي طورتها.
سنتعلم في هذا الدرس كيفيَّة تمرير عدد متغير من الوسائط إلى دالة ما باستخدام الصياغتين *args
و **kwargs
.
الوسيط *args
في بايثون، يمكن استخدام الشكل أحادي النجمة *args
كمعامل لتمرير قائمة غير محددة الطول من الوسائط غير المسماة (non-keyworded argument) إلى الدوال. تجدر الإشارة إلى أنّ النجمة (*
) عنصر ضروري هنا، إذ رغم أنّ الكلمة args
متعارف عليها بين المبرمجين، إلا أنها غير رسمية.
لنلقِ نظرة على مثال لدالة تستخدم وسيطين:
def multiply(x, y): print (x * y)
عرّفنا في الشفرة أعلاه دالة تقبل وسيطين x
و y
، عندما نستدعي هذه الدالة، سنحتاج إلى تمرير عددين موافقين للوسيطين x
و y
. في هذا المثال، سنمرّر العدد الصحيح 5
إلى x
، والعدد الصحيح 4
إلى y
:
def multiply(x, y): print (x * y) multiply(5, 4)
عند تنفيذ الشفرة أعلاه:
python lets_multiply.py
سنحصل على المخرجات التالية:
20
ماذا لو قررنا لاحقًا أننا نود حساب ناتج ضرب ثلاثة أعداد بدلًا من عددين فقط؟ إذا حاولت تمرير عدد إضافي إلى الدالة، كما هو موضح أدناه:
def multiply(x, y): print (x * y) multiply(5, 4, 3)
فسيُطلَق الخطأ التالي:
TypeError: multiply() takes 2 positional arguments but 3 were given
إذا شككت أنك ستحتاج إلى استخدام المزيد من الوسائط لاحقًا، فالحل هو استخدام *args
كمعامل.
سنزيل المُعاملين x
و y
من الشفرة في المثال الأول، ونضع مكانهما *args
:
def multiply(*args): z = 1 for num in args: z *= num print(z) multiply(4, 5) multiply(10, 9) multiply(2, 3, 4) multiply(3, 5, 10, 6)
عندما ننفّذ هذه الشفرة، سنحصل على ناتج استدعاءات الدالة أعلاه:
20 90 24 900
يمكننا باستخدام الوسيط *args
تمرير أي عدد نحب من الوسائط عند استدعاء الدالة بالإضافة إلى كتابة شيفرة أكثر مرونة، وإنشاء دوال تقبل عددًا غير محدد مسبقًا من الوسائط غير المسماة.
الوسيط **kwargs
يُستخدَم الشكل ذو النجمتين **kwargs
لتمرير قاموس متغير الطول من الوسائط المسماة إلى الدالة المعرّفة. مرة أخرى، النجمتان (**
) ضروريتان، فمع أنّ استخدام الكلمة kwargs
متعارف عليه لدى المبرمجين، إلا أنها غير رسمية.
يمكن أن تأخذ **kwargs
، كما هو شأن *args
، أيّ عدد من الوسائط التي ترغب في تمريرها إلى الدالة بيْد أنّ **kwargs
تختلف عن *args
في أنها تستوجب تعيين أسماء المعاملات (keywords).
في المثال التالي، ستطبع الدالة الوسيط **kwargs
الممرر إليها.
def print_kwargs(**kwargs): print(kwargs)
سنستدعي الآن الدالة ونمرر إليها بعض الوسائط المسماة:
def print_kwargs(**kwargs): print(kwargs) print_kwargs(kwargs_1="Shark", kwargs_2=4.5, kwargs_3=True)
لننفذ البرنامج أعلاه:
python print_kwargs.py
سنحصل على المخرجات التالية:
{'kwargs_3': True, 'kwargs_2': 4.5, 'kwargs_1': 'Shark'}
اعتمادًا على إصدار بايثون 3 الذي تستخدمه، فقد لا يكون القاموس مرتبًا. في بايثون 3.6 وما بعده، ستحصل على أزواج قيمة-مفتاح (key-value) مرتبة، ولكن في الإصدارات السابقة، سيكون ترتيب الأزواج عشوائيًا.
سيُنشَأ قاموس يسمى kwargs
، والذي يمكننا التعامل معه مثل أي قاموس عادي داخل الدالة.
لننشئ برنامجًا آخر لإظهار كيفية استخدام **kwargs
. سننشئ دالة تطبع قاموسًا من الأسماء. أولاً، سنبدأ بقاموس يحتوي اسمين:
def print_values(**kwargs): for key, value in kwargs.items(): print("The value of {} is {}".format(key, value)) print_values(my_name="Sammy", your_name="Casey")
بعد تنفيذ البرنامج:
python print_values.py
سنحصل على مايلي:
The value of your_name is Casey The value of my_name is Sammy
قد لا تكون القواميس مرتَّبة، لذلك قد يظهر الاسم Casey
أولاً، وقد يظهر ثانيًا.
سنمرر الآن وسائط إضافية إلى الدالة لنرى كيف يمكن أن تقبل **kwargs
أيّ عدد من الوسائط:
def print_values(**kwargs): for key, value in kwargs.items(): print("The value of {} is {}".format(key, value)) print_values( name_1="Alex", name_2="Gray", name_3="Harper", name_4="Phoenix", name_5="Remy", name_6="Val" )
إذا نفّذنا البرنامج الآن، فسنحصل على المخرجات التالية، والتي قد تكون غير مرتبة:
The value of name_2 is Gray The value of name_6 is Val The value of name_4 is Phoenix The value of name_5 is Remy The value of name_3 is Harper The value of name_1 is Alex
يتيح لك استخدام **kwargs
مرونةً كبيرةً في استخدام الوسائط المسماة. فعند استخدامها، لن نحتاج إلى معرفة مسبقة بعدد الوسائط التي ستمرر إلى الدالة.
ترتيب الوسائط
عند الخلط بين عدة أنواع من الوسائط داخل دالة، أو داخل استدعاء دالة، يجب أن تظهر الوسائط وفق الترتيب التالي:
- الوسائط العادية
-
*args
- الوسائط المسمّاة
-
**kwargs
عمليًا، عند الجمع بين المعاملات العادية، والوسيطين *args
و **kwargs
، فينبغي أن تكون وفق الترتيب التالي:
def example(arg_1, arg_2, *args, **kwargs): ...
وعند الجمع بين المعاملات العادية والمعاملات المسماة و *args
و **kwargs
، ينبغي أن تكون وفق الترتيب التالي:
def example2(arg_1, arg_2, *args, kw_1="shark", kw_2="blobfish", **kwargs): ...
من المهم أن تأخذ في الحسبان ترتيب الوسائط عند إنشاء الدوال حتى لا تتسبب في إطلاق خطأٍ متعلقٍ بالصياغة.
استخدام *args
و **kwargs
في استدعاءات الدوال
يمكننا أيضًا استخدام *args
و **kwargs
لتمرير الوسائط إلى الدوال. أولاً، دعنا ننظر إلى مثال يستخدم *args
:
def some_args(arg_1, arg_2, arg_3): print("arg_1:", arg_1) print("arg_2:", arg_2) print("arg_3:", arg_3) args = ("Sammy", "Casey", "Alex") some_args(*args)
في الدالة أعلاه، هناك ثلاثة معاملات، وهي arg_1
و arg_
و arg_3
. ستطبع الدالة كل هذه الوسائط. بعد ذلك أنشأنا متغيرًا، وأَحلنا عليه عنصرًا تكراريًا (في هذه الحالة، صف)، ثم مرَّرنا ذلك المتغير إلى الدالة باستخدام الصياغة النجمية (asterisk syntax).
عندما ننفّذ البرنامج باستخدام الأمر python some_args.py
، سنحصل على المخرجات التالية:
arg_1: Sammy arg_2: Casey arg_3: Alex
يمكننا أيضًا تعديل البرنامج أعلاه، واستخدام قائمة. سندمج أيضًا *args
مع وسيط مسمى:
def some_args(arg_1, arg_2, arg_3): print("arg_1:", arg_1) print("arg_2:", arg_2) print("arg_3:", arg_3) my_list = [2, 3] some_args(1, *my_list)
إذا نفذنا البرنامج أعلاه، فسنحصل على المخرجات التالية:
arg_1: 1 arg_2: 2 arg_3: 3
وبالمثل، يمكن استخدام الوسائط المسماة **kwargs
لاستدعاء دالة.
سننشئ متغيرًا، ونسند إليه قاموسًا من 3 أزواج مفتاح-قيمة (سنستخدم kwargs
هنا، ولكن يمكنك تسميته ما تشاء)، ثم نُمرِّره إلى دالة ذات 3 وسائط:
def some_kwargs(kwarg_1, kwarg_2, kwarg_3): print("kwarg_1:", kwarg_1) print("kwarg_2:", kwarg_2) print("kwarg_3:", kwarg_3) kwargs = {"kwarg_1": "Val", "kwarg_2": "Harper", "kwarg_3": "Remy"} some_kwargs(**kwargs)
عند تنفيذ البرنامج أعلاه باستخدام الأمر python some_kwargs.py
، سنحصل على المخرجات التالية:
kwarg_1: Val kwarg_2: Harper kwarg_3: Remy
خلاصة
يمكنك استخدام الصياغتين الخاصتين *args
و **kwargs
ضمن تَعاريف الدوال لتمرير أيّ عدد تشاء من الوسائط إليها.
يُستحسن استخدام *args
و **kwargs
في المواقف التي تتوقع أن يظل فيها عدد المدخلات في قائمة الوسائط صغيرًا نسبيًا. وضع في ذهنك أن استخدام *args
و **kwargs
يحسِّن مقروئية الشيفرة، ويسهِّل على المبرمجين، ولكن ينبغي استخدامهما بحذر.
هذه المقالة جزء من سلسة مقالات حول تعلم البرمجة في بايثون 3.
ترجمة -وبتصرّف- للمقال How To Use *args and **kwargs in Python 3 لصاحبته Lisa Tagliaferri
اقرأ أيضًا
- المقالة التالية: كيفية إنشاء الأصناف وتعريف الكائنات في بايثون 3
- المقالة السابقة: كيفية تعريف الدوال في بايثون 3
- المرجع الشامل إلى تعلم لغة بايثون
- كتاب البرمجة بلغة بايثون
أفضل التعليقات
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.