My name is Adam and I'm 25 years old
5 استدعاء الإجراءات
الإجراء (Procedure) هو جزء محفوظ من البرنامج يتم استدعاؤه مع تمرير عوامل مختلفة.
ويمكن استدعاؤه (Call) بعامل واحد:
- نحو:
int(x)
لإنشاء العدد الصحيح من النص. مثل:int("12")
ينتج:12
. - أو نحو:
abs(x)
للقيمة المطلقة مثل:abs(-10)
ينتج:10
.
وقد يأخذ عاملين:
- نحو:
round(x, n)
مثل:round(10.259, 2)
ينتج:10.26
. - أو نحو:
pow(x, y)
لرفع العددx
إلى القوةy
. مثل:pow(2, 3)
ينتج:8
.
وقد يأخذ عاملاً واحدًا لكنَّهُ قائمة:
- نحو:
sum(numbers)
مثل:sum([1, 2, 3, 4, 5])
ينتج:15
. - أو نحو:
max(numbers)
لأكبر عدد في القائمة. مثل:max([1, 2, 30, 4, 5])
ينتج:30
.
وقد يكون عدد عوامله لا محدودًا:
- نحو:
print(*values)
. فعلامة النجمة (*
) تشير لقبول عدد مطلق من العوامل. مثل:
فإن print
قبلت خمسة عوامل:
- النص:
"My name is"
- قيمة المتغير:
name
- النص:
"and I'm"
- قيمة المتغير:
age
- النص:
"years old"
ولدينا الإجراء help(func)
يطلب مساعدة الإجراء المعيَّن، بلا أقواس، هكذا:
Help on built-in function sum in module builtins:
sum(iterable, /, start=0)
Return the sum of a 'start' value (default: 0) plus an iterable of numbers
When the iterable is empty, return the start value.
This function is intended specifically for use with numeric values and may
reject non-numeric types.
وقد عرفت أن طلب التنفيذ يكون بالقوسين بعد اسمه ()
، وتوضَع العوامل فيهما وهي ضربان:
- عامل مؤثر
- عامل متأثر
وفي كل ما سبق كانت العوامل من النوع المؤثر؛ لأنها كانت تؤثر في النتيجة ولا تتأثر بها.
أما المتأثر فنحو فعل الترتيب من مكتبة القائمة: list.sort(xs)
فإن المتأثر به القائمة نفسها، مثل:
فأما جملة list.sort
فإننا حددنا اسم النوع list
وأردنا منه الإجراء sort
، وأتينا بالقوسين لطلب تنفيذه، ووضعنا المتأثر xs
فيه.
ومع أننا لم نعيِّن النتيجة (بجملة التعيين =
)، فقد تغيَّرت (تأثرت) القائمة بالإجراء:
بعكس الترتيب بالإجراء الذي ليس من النطاق العام: sorted(xs)
فإنَّ القائمة فيه ليست متأثرًا؛ إذْ يُنتِجُ الإجراءُ قائمةً جديدةً ولا يغير القائمة المُدخلة:
xs = [40, 20, 10, 30]
ys = sorted(xs)
print(xs, "لم يعمل الإجراء في القائمة نفسها")
print(ys, "هي قائمة جديدة")
[40, 20, 10, 30] لم يعمل الإجراء في القائمة نفسها
[10, 20, 30, 40] هي قائمة جديدة
وقد تتساءل ما الفائدة من وجود طريقتين وكلاهما يعمل نفس العمل؟
- الطريقة الأولى:
list.sort(xs)
لا ترجع بشيء بل تعدل نفس القائمة - الطريقة الثانية:
sorted(xs)
ترجع قائمة جديدة
فأما الطريقة الأولى فأصغر في الذاكرة لأنها لا تُنشئ نُسخة كما تفعل الطريقة الثانية. لكن الطريقة الثانية مفيدة إن أردت أن تُبقي القائمة الأصلية كما هي.
والأمر كذلك في الإجراءين:
list.reverse(xs)
reversed(xs)
ويجتمع المؤثر والمتأثر في نحو:
فالإجراء list.append
يأخذ القائمة، ويضيف إليها القيمة 50
. ولذلك نقول الأوَّل متأثر والثاني مؤثر.
وقد وضعت اللغات الشيئية (Object-Oriented) مثل بايثون صياغة خاصَّةً: للإجراء المسند إلى الشيء. وبذلك يتحصل لدينا طريقتان كلتاهما تؤديان نفس المعنى:
- إسناد الإجراء للنوع:
list.append(xs, 25)
- إسناد الإجراء للشيء:
xs.append(25)
ومثاله أيضًا في الإجراء list.sort
للترتيب وكذلك في list.append
للإضافة:
وسنفرد للبرمجة الشيئية باباً.
وقد تُعَيَّنُ العوامل بأحد طريقتين:
- تعيين بالموضع: نحو:
round(3.14159, 2)
- تعيين بالاسم: نحو:
round(number=3.14159, ndigits=2)
فلا يشترط فيه ترتيب العوامل.
ويجوز استعمال الطريقتين معًا في نحو: list.sort(numbers, reverse=True)
ويشترط فيه تقدم التعيين بالموضع ليكون في مكانه، ثم يتبعه التعيين بالاسم حيث لا يشترط الترتيب فيه.