English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
الزخرف يقبل دالة ويضيف بعض الوظائف ويقوم بتقديمها. في هذا المقال، ستتعلم كيفية إنشاء الزخرف وأهمية استخدامها.
يحتوي بايثون على وظيفة مثيرة للاهتمام تُدعىالزخارف، بإمكانها إضافة وظائف إلى الكود الموجود بالفعل.
وذلك يُسمى أيضًاالمبرمجة العليا،لأن جزءًا من البرنامج يحاول تعديل جزء آخر من البرنامج عند التجميع.
للتفهم المزخرفات، يجب أن نفهم أولاً بعض المعارف الأساسية لبايثون.
يجب أن نتقبل حقيقة أن كل شيء في بايثون هوالكائنات. الأسماء التي نصنعها هي مجرد مؤشرات مرتبطة بهذه الكائنات.الدواللا يختلف الأمر عن ذلك، فهي كذلك كائنات (تحتوي على خصائص). يمكن ربط أسماء مختلفة بنفس كائن الوظيفة.
هذا مثال.
def first(msg): print(msg) first("Hello") second = first second("Hello")
عند تشغيل الكود، تعطي الدوال first و second نفس الخروج. هنا، تشير الأسماء first و second إلى نفس كائن الوظيفة.
الآن، قد يبدو الأمر معقدًا بعض الشيء، يمكن أن يتم تمرير الدوال كمعلمات إلى دالة أخرى.
إذا كنت قد استخدمت map، filter و reduce في بايثون، فإنك تعرف هذا بالفعل.
تُدعى هذه الدوال أيضًاالدوال العليا. هذا مثال على هذا النوع من الدوال.
def inc(x): return x + 1 def dec(x): return x - 1 def operate(func, x): result = func(x) return result
نحن ندعو الدوال كما يلي.
>>> operate(inc, 3) 4 >>> operate(dec, 3) 2
إضافة إلى ذلك، يمكن أن تعود دالة واحدة بدالة أخرى.
def is_called(): def is_returned(): print("Hello") return is_returned new = is_called() #إخراج "Hello" new()
في هذا السياق، is_returned() هي دالة محاطة، تُعرف وتُعيد كل مرة نُدعو is_drawn().
في النهاية، يجب أن نفهمالمغلق في بايثون.
تُدعى الدوال والطُرققابل للإشارة،بما أن يمكن تفعيلها.
في الواقع، أي كائن يحتوي على طريقة خاصة __call__() يُعتبر قابل للإشارة. لذا، من الناحية الأساسية، المزخرفات قابلة للإشارة، قابلة للإرجاع.
بشكل عام، المزخرفات تأخذ دالة، تضيف بعض الوظائف وتعيد إياها.
def make_pretty(func): def inner(): print("أنا مزخرف") func() إرجاع inner def ordinary(): print("أنا دالة عادية")
عند تشغيل الكود التالي في shell،
>>> ordinary() أنا دالة عادية >>> # دعونا نزين هذه الدالة العادية >>> pretty = make_pretty(ordinary) >>> pretty() لقد تم تزييني أنا دالة عادية
في المثال الذي تم عرضه أعلاه، make_pretty() هو محول. في خطوة التخصيص.
pretty = make_pretty(ordinary)
تم تزيين الدالة ordinary()، الدالة التي تم إرجاعها تُسمى pretty.
يمكننا رؤية أن الدالة المحولة أضافت بعض الوظائف الجديدة إلى الدالة الأصلية. هذا يشبه تزيين الهدية. المحول يشبه اللفائف. لا تتغير طبيعة الهدية (الهدية داخل المحول) ولكن الآن تبدو جميلة (منذ تزيينها).
عادة، نزين دالة ونعيد تخصيصها
ordinary = make_pretty(ordinary).
هذا بناء شائع لذا قدمت لغة بايثون لغة بسيطة لتحقيق هذا.
يمكننا استخدام رمز @ مع اسم دالة المحول وإقامته في أعلى تعريف الدالة التي نريد تزيينها. على سبيل المثال،
@make_pretty def ordinary(): print("أنا دالة عادية")
يساوي
def ordinary(): print("أنا دالة عادية") ordinary = make_pretty(ordinary)
هذا مجرد حلاوة لغة البرمجة لتحقيق محول.
المحول في الأعلى بسيط للغاية وهو ينطبق فقط على الدوال التي لا تحتوي على أي معلمات. ماذا إذا كانت لدينا دالة مثل تلك التي تظهر هنا؟
def divide(a, b): return a/b
يملك هذا الدالة اثنين من المعلمات،aوb. نحن نعلم أننا إذا قمنا بـbإذا تم إرسال صفر، فإن ذلك سيؤدي إلى خطأ.
>>> divide(2,5) 0.4 >>> divide(2,0) Traceback (أحدث استدعاء أخر): ... ZeroDivisionError: قسمة بالصفر
دعونا نصنع محولًا لتحقق مما إذا كان هذا سيؤدي إلى خطأ.
def smart_divide(func): def inner(a,b): print("أريد أن أقوم بضرب", a, "و", b) if b == 0: print("يا إلهي! لا يمكنني القسمة") return return func(a,b) إرجاع inner @smart_divide def divide(a,b): return a/b
إذا ظهرت حالة خطأ، فإن هذا التحقق الجديد سيعود بلا شيء (None).
>>> divide(2,5) أريد أن أقوم بضرب 2 و 5 0.4 >>> divide(2,0) أريد القيام بالتقسيم 2 و 0 اه! لا يمكن تقسيم
باستخدام هذا الأسلوب، يمكننا تزيين الوظائف التي تحتوي على معاملات.
سيفهم المراقب الحذر أن معاملات الدالة المدمجة في المزخرف inner() هي نفسها كما في الدالة التي يتم تزيينها. وبتأمل في ذلك، يمكننا الآن جعل المزخرفات العامة تستخدم أي عدد من المعاملات.
في بيان، يتم إنجاز هذا السحر من خلالfunction(*args, **kwargs). وبالتالي، args هي المعاملات الموضعية،الجماعاتبدلاً من kwargs هو المعاملات المفتوحةالمفاهيم. مثال على هذا النوع من المزخرفات هو.
def works_for_all(func): def inner(*args, **kwargs): print("أستطيع تزيين أي وظيفة") إرجاع func(*args, **kwargs) إرجاع inner
يمكن ربط عدة مزخرفات في بيان.
هذا يعني أن يمكن تزيين وظيفة بأدوات تزيين مختلفة (أو متشابهة) مرات عديدة. كل ما علينا القيام به هو وضع أدوات التزيين فوق الوظيفة المطلوبة.
def star(func): def inner(*args, **kwargs): print("*" * 30) func(*args, **kwargs) print("*" * 30) إرجاع inner def percent(func): def inner(*args, **kwargs): print("%" * 30) func(*args, **kwargs) print("%" * 30) إرجاع inner @star @percent def printer(msg): print(msg) printer("Hello")
سيكون هذا الناتج.
****************************** %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% مرحبا %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ******************************
اللغة السابقة،
@star @percent def printer(msg): print(msg)
يساوي
def printer(msg): print(msg) printer = star(percent(printer))
ترتيب الروابط المزخرفة مهم. إذا كنا نتبع النظام العكسي،
@percent @star def printer(msg): print(msg)
سيتم تنفيذ
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ****************************** مرحبا ****************************** %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%