الدالة functools.update_wrapper()‎ في بايثون

من موسوعة حسوب

تُحدّث الدّالة functools.update_wrapper()‎ دالّة مُحيطةً (wrapper) لتبدوَ مثل الدّالة المُحاطة (wrapped).

المُعاملات الاختياريّة هي صفوفٌ تُستخدم لتحديد أيّ خاصيّات الدّالة الأصليّة ستُعيّن مُباشرة للخاصيّات الموافقة لها على الدّالة المُحيطة وأيّ الخاصيّات من خاصيّات الدّالة المُحيطة ستُحدَّثُ بالخاصيّات المُوافقة لها في الدّالة الأصليّة. القيم الافتراضيّة لهذه المُعاملات هي الثّوابت المُتاحة على مستوى الوحدة:

  • WRAPPER_ASSIGNMENTS‎: والتي تُعيّن كلّا من ‎__module__‎، و‎__name__‎، و‎__qualname__‎، و‎__annotations__‎‎، و‎__doc__‎‎، التي تُعدّ خاصيّاتٍ تُضيف معلومات حول الدّالة.
  • WRAPPER_UPDATES‎: التي تُحدّث خاصيّة ‎__dict__‎ الخاصّة بالدّالة المُحيطة، أي قاموس النّسخة (the instance dictionary) الخاصّ بها.

تُضيف هذه الدّالة الخاصيّة ‎__wrapped__‎ إلى الدّالة المُحيطة، وهذه الخاصيّة تُشير إلى الدّالة المُحاطة، وذلك للتّمكن من الوصول إلى الدّالة الأصليّة للتحقيق فيها (تجاهل مُزخرف تخبئة مثل المزخرف functools.lru_cache() مثلًا).

تُستخدم هذه الدّالة أساسًا في الدّوال المُزخرِفة (decorator functions) التي تُحيط الدّالة المُزخرفَة وتُعيد الدّالة المُحيطة. إن لم تُحدَّث الدّالة المُحيطة، فالبيانات الوصفيّة (metadata) الخاصّة بالدّالة المُعادة ستُشير إلى تعريف الدّالة المُحيطة عوضًا عن تعريف الدّالة الأصليّة، الشيء الذي لا يكون مُفيدًا عادةً.

يُمكن استخدام الدّالة functools.update_wrapper()‎ مع الكائنات القابلة للاستدعاء الأخرى التي لا تكون دوالا. الخاصيّات التي تكون في الصّف assigned‎ أو الصّف updated والتي تكون مفقودةً في الكائن المُحاط ستُتجاهَل (ولن تُحاول هذه الدّالة ضبط قيم لهذه الخاصيّات على الدّالة المُحيطة). يُطلق الاستثناء AttributeError إن كانت الدّالة المُحيطة تفتقد أحد الخاصيّات المذكورة في الصّف updated.

البنية العامة

functools.update_wrapper(wrapper, wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)

المعاملات

wrapper

الدّالة المُحيطة.

wrapped

الدّالة المُحاطة.

assigned

الخاصيّات التي ستُعيّن.

updated

الخاصيّات التي ستُحدّث.

القيمة المعادة

تُحدّث دالّة مُحيطةً لتبدوَ مثل الدّالة المُحاطة.

أمثلة

المثال التّالي يوضّح كيفيّة إنشاء دالة مُحيطة دون تحديثها بالدّالة، لاحظ أنّ اسم الدّالة خطأ:

>>> def to_str(function):
...     def str_val(*args, **kwargs):
...         result = function(*args, **kwargs)
...         return str(result)
...     return str_val # هنا نُعيد الدّالة المُحيطة
... 
>>> @to_str
... def square(n):
...     return n*n
... 
>>> square(40)
'1600'

>>> square.__name__ # اسم الدّالة خطأ
'to_str'

وهنا نُحدّث الدّالة المُحيطة لتبدو مثل الدّالة المُحاطة، لاحظ أنّ اسم الدّالة المُحاطة أصبح يُعبّر عنها بشكل صحيح:

>>> def to_str(function):
...     def str_val(*args, **kwargs):
...         result = function(*args, **kwargs)
...         return str(result)
...     return functools.update_wrapper(str_val, function) # نُحدّث الدّالة المُحيطة بالدّالة الأصليّة قبل إعادتها
... 

>>> @to_str
... def _square(n):
...     return n*n
... 


>>> _square.__name__ # اسم الدّالة صحيح
'_square'

انظر أيضًا

مصادر