المشاركة الأصلية بواسطة علي الشمري مشاهدة المشاركة
أحتجت قبل فترة الى تمرير دالة ذات متغييرات الى دالة أخرى عند عمل Call لها في لغة بايثون وبالبداية لم أصل الى نتيجة بسبب إنني كنت أرسل المتغييرات التابعة للدالة التي أريد إرسالها للدالة الأخرى بشكل خاطيء … يعني لنفرض لدي الدوال التالية:

كود:
[LEFT]>>> def Caller(func):
...     func()
... 
[/LEFT]
بعد ذلك عرفنا دالة أخرى:

كود:
[LEFT]>>> def customTax(price, tax=0.16):
...     return price + (price * tax)
...
[/LEFT]
الآن لنجرب مناداة الدالة الثانية من خلال الدالة الأولى:

كود:
[LEFT]>>> x = Caller(customTax(100))
Traceback (most recent call last):
  File "", line 1, in 
  File "", line 2, in Caller
TypeError: 'float' object is not callable[/LEFT]
كما تلاحظون كنت أحصل على خطأ … طيب والحل؟ الحل بسيط، هو أن نقوم بتمرير القييم أو المتغييرات المرادة الى الدالة الأصلية من خلال تمريرها على شكل متغييرات للدالة الأولى، يعني تصبح الدالة الأولى Caller كما يلي:

كود:
[LEFT]>>> def Caller(func, *funcargs):
...     return func(*funcargs)
[/LEFT]
كوننا لا نعلم كم متغيير ممكن تأخذ الدلة التي نريد تنفيذها من خلال Caller أستعملنا إشارة النجمة “*” وذلك لكي نتمكن من تمرير أكثر من متغيير … الآن لتنفيذ الدالة customTax نعمل التالي:

كود:
[LEFT]>>> x = Caller(customTax, 100)
>>> x
116.0[/LEFT]
أو هكذا أيضاً ممكن:

كود:
[LEFT]>>> x = Caller(customTax, 100,0.12)
>>> x
112.0[/LEFT]
لكن لنفرض عرفنا دالة بهذا الشكل:

كود:
[LEFT]>> def Welcome(who):
...     print "Hello " + str(who)
[/LEFT]
أي لا تقوم بعملية إرجاع لأي قيمة (لا يوجد return) … فعند تنفيذها عبر Caller وتخزين الناتج في x مثلاً، فإنه فعلياً لن يخزن في x شيء ! أو لنكون دقيقين أكثر، سوف يتخزن فيه None ولكن لو طبعنا x مباشرة على الـ interpreter لن نرى شيء، إلا لو نفذنا الأمر print x … على كل أنظر معي:

كود:
[LEFT]>>> x = Caller(Welcome, 'Binary')
Hello Binary[/LEFT]
ولو نفذنا:

كود:
[LEFT]>>> x[/LEFT]
فلن نحصل على شيء كما ذكرت … ولهذا لنرى كلمة None نطبع x هكذا:

كود:
[LEFT]>>> print x
None
[/LEFT]
السبب إنه None هو كون الدالة Welcome لا تقوم بعملية إرجاع لأي قيمة … وفي Python حين نقوم بتخزين ناتج دالة لا ترجع قيمة في متغيير فإنه يكون عبارة عن None … وللتأكيد أكثر:

كود:
[LEFT]>>> type(x)
<type 'NoneType'>
[/LEFT]
كما تلاحظون NoneType … وبالتالي لمناداة مثل هذه الدوال ممكن ذلك بشكلها الصحيح:

كود:
[LEFT]>>> Caller(Welcome, 'Binary')
Hello Binary[/LEFT]
أي نقوم بمناداة للدالة بشكل مباشر بدون الحاجة الى تخزين الناتج، كون الدالة الذي نريد منادتها Welcome أصلا لا ترجع قيمة … أتمنى يكون هذا الموضوع مفيد لأحدكم وإن شاء الله أستمر في كتابة ما يمر من أمامي حول لغة بايثون للفائدة العامة ولكي أوثق الأمور لنفسي لعلي أحتاجها بالمستقبل مرة أخرى …

دمتم بود …