تمرير المعاملات Parameters Passing فى Python

عند استدعاء اي دالة وعند تمرير المعاملات يتم تمريره فى لغات البرمجة عن طريق ام عن طريق الاستدعاء على حسب القيمة call by value او الاستدعاء على حسب المرجع  call by reference.

Call by Value

الطريقة الاشهر والاكثر استخدامًا وهى تمرير القيمة للدالة عن استدعائها وتستخدم هذه الطريقة فى لغة C و لغة ++C.

ويتم ذلك عن طريق اخذ نسخة من قيمة المعامل فعند التعديل على قيمة هذا المتغير داخل الدالة Local Scope لن يتم التأثير علي قيمته بعد اتنهاء الدالة.

مثال للتوضيح بلغة C

#include <stdio.h>
int increment(int var)
{
    var = var+1;
    return var;
}

int main()
{
   int num1=20;
   int num2 = increment(num1);
   printf("num1 value is: %d", num1);
   printf("\nnum2 value is: %d", num2);

   return 0;
}

فى المثال السابق بلغة C يتم استدعاء الدالة increment وتمرير المعامل num1 بعد ذلك يتم التعامل مع نسخة من قيمة المتغير وليس المتغير نفسه داخل الدالة لذلك عن طباعة قيمة num1 بعد استدعاء الدالة نجد انه لايتغير -لان الدالة تعاملت مع نسخه من وليس المتغير نفسه.

الخرج للكود السابق

num1 value is: 20
num2 value is: 21

Call by Reference

الاستراتيجية الاخرى لتمرير المعاملات هى Reference , فى هذه الطريقة بدلًا من تمرير نسخة من قيمة المتغير إلى الدالة يتم تمرير العنوان الذى يشير إلى هذا المتغير بمعنى انه عندما يتم التغيير فى قيمة المتغير داخل الدالة سيؤثر ذلك على المتغير الاصلى وليس نسخة منه.

تدعم العديد من لغات البرمجة Call by Reference ، مثل C أو C ++ ، لكن Perl تستخدمه بشكل افتراضي.

مثال للتوضيح بلغة C

#include<stdio.h>  
void change(int *num) {    
    printf("Before adding value inside function num=%d \n",*num);    
    (*num) += 100;    
    printf("After adding value inside function num=%d \n", *num);    
}      
int main() {    
    int x=100;    
    printf("Before function call x=%d \n", x);    
    change(&x);//passing reference in function    
    printf("After function call x=%d \n", x);    
return 0;  
}

الخرج

Before function call x=100
Before adding value inside function num=100
After adding value inside function num=200
After function call x=200

فى المثال السابق عند التغير فى قيمة x داخل الدالة change يتم التغيير فى النسخة الاصلية x. لذلك عن طباعة قيمة المتغير x بعد تنفيذ الدالة نجد القيمه 200.

الآن ماذا عن الطريقة المستخدمة فى Python

الحقيقة ان هناك نوع ثالث من طرق تمرير المعامل وهى Pass by object reference وهو الاسلوب الذى تستخدمه لغة python.

فى بايثون عندم تقوم بعمليه Assign اي وضع قيمة معينة فى متغير فأنك تحجز مكان فى الذاكرة وتجعل متغير معين يشير لهذا المكان فى الذاكرة على سبيل المثال

x = 20

عند تمرير متغيرات غير قابل للتغيير immutable  مثل integers و strings و tuples فالدالة تتعامل بطريقة شبيهة لل call-by-value.

مثال

def ref_demo(x):
    x=42
x=10
ref_demo(x)
print(x)

الخرج يكون 10

ام فى حالة قمنا بتمرير متغير من النوع mutable اي قابل للتغيير مثل lists او objects فهناك حالتين

فى حالة التغيير على المتغير فى نفس المكان فى الذاكرة in-place فى هذه الحالة يتم التعامل على انها call-by-reference  مثل المثال القادم.

مثال

def append_one(li):
    li.append(1)
x = [0]
append_one(x)
print x

لان المتغير li مازال يشير على نفس القيمة فى الذاكرة حتى بعد تغيرها بالتالى التغييرات تكون فى المتغير الاصلى.

ام فى حالة اعادة Assign يتم التحويل إلى سلوك شبيه ب Call-by-value 

مثال

def append_one(li):
    li = [0, 1]
x = [0]
append_one(x)
print x

والخرج يكون

[0]

  لانه عند اعادة assign ل li داخل الدالة فان li يشير على مكان جديد فى الذاكرة وبالتالى التغييرات داخل الدالة لن تغير فى الاصل.


كتب بواسطة عمرو العربى

مؤسس مطور

التعليقات

اترك تعليقك

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *

*