أحتجت قبل فترة الى تمرير دالة ذات متغييرات الى دالة أخرى عند عمل Call لها في لغة بايثون وبالبداية لم أصل الى نتيجة بسبب إنني كنت أرسل المتغييرات التابعة للدالة التي أريد إرسالها للدالة الأخرى بشكل خاطيء … يعني لنفرض لدي الدوال التالية:
>>> def Caller(func):
... func()
...
بعد ذلك عرفنا دالة أخرى:
>>> def customTax(price, tax=0.16):
... return price + (price * tax)
...
الآن لنجرب مناداة الدالة الثانية من خلال الدالة الأولى:
>>> x = Caller(customTax(100))
Traceback (most recent call last):
File "", line 1, in
File "", line 2, in Caller
TypeError: 'float' object is not callable
كما تلاحظون كنت أحصل على خطأ … طيب والحل؟ الحل بسيط، هو أن نقوم بتمرير القييم أو المتغييرات المرادة الى الدالة الأصلية من خلال تمريرها على شكل متغييرات للدالة الأولى، يعني تصبح الدالة الأولى Caller كما يلي:
>>> def Caller(func, *funcargs):
... return func(*funcargs)
كوننا لا نعلم كم متغيير ممكن تأخذ الدلة التي نريد تنفيذها من خلال Caller أستعملنا إشارة النجمة “*” وذلك لكي نتمكن من تمرير أكثر من متغيير … الآن لتنفيذ الدالة customTax نعمل التالي:
>>> x = Caller(customTax, 100)
>>> x
116.0
أو هكذا أيضاً ممكن:
>>> x = Caller(customTax, 100,0.12)
>>> x
112.0
لكن لنفرض عرفنا دالة بهذا الشكل:
>> def Welcome(who):
... print "Hello " + str(who)
أي لا تقوم بعملية إرجاع لأي قيمة (لا يوجد return) … فعند تنفيذها عبر Caller وتخزين الناتج في x مثلاً، فإنه فعلياً لن يخزن في x شيء ! أو لنكون دقيقين أكثر، سوف يتخزن فيه None ولكن لو طبعنا x مباشرة على الـ interpreter لن نرى شيء، إلا لو نفذنا الأمر print x … على كل أنظر معي:
>>> x = Caller(Welcome, 'Binary')
Hello Binary
ولو نفذنا:
>>> x
فلن نحصل على شيء كما ذكرت … ولهذا لنرى كلمة None نطبع x هكذا:
>>> print x
None
السبب إنه None هو كون الدالة Welcome لا تقوم بعملية إرجاع لأي قيمة … وفي Python حين نقوم بتخزين ناتج دالة لا ترجع قيمة في متغيير فإنه يكون عبارة عن None … وللتأكيد أكثر:
>>> type(x)
كما تلاحظون NoneType … وبالتالي لمناداة مثل هذه الدوال ممكن ذلك بشكلها الصحيح:
>>> Caller(Welcome, 'Binary')
Hello Binary
أي نقوم بمناداة للدالة بشكل مباشر بدون الحاجة الى تخزين الناتج، كون الدالة الذي نريد منادتها Welcome أصلا لا ترجع قيمة … أتمنى يكون هذا الموضوع مفيد لأحدكم وإن شاء الله أستمر في كتابة ما يمر من أمامي حول لغة بايثون للفائدة العامة ولكي أوثق الأمور لنفسي لعلي أحتاجها بالمستقبل مرة أخرى …
دمتم بود …
أحب متابعة مدونتك، خصوصًا لو كانت متعلقة بلغة بايثون. أشكرك على الموضوع.
Ibrahim Alghamdi@ حياك الله اخي إبراهيم، إن شاء الله نواصل الكتابة عن بايثون وباقي الأمور … سررت بمرورك وإعجابك بالأمور البسيطة التي هنا …