كيفية استخدام ديكورات بايثون لتحسين الوظائف

تُعد مُزيِّنات Python طريقة فعّالة ومرنة لتعديل أو تحسين الوظائف والطرق. توفر المُزيِّنات طريقة لتغليف وظيفة بوظائف إضافية، مما يسمح لك بتوسيع سلوكها دون تعديل الكود الفعلي الخاص بها. ستقدم لك هذه المقالة مفهوم المُزيِّنات، وكيفية إنشائها واستخدامها، واستكشاف بعض الأمثلة العملية.

ما هو المُزيّن؟

المُزيِّن هو دالة تأخذ دالة أخرى وتوسع سلوكها دون تعديله صراحةً. في بايثون، تُستخدم المُزيِّنات غالبًا لإضافة وظائف مثل التسجيل أو التحكم في الوصول أو قياس الأداء إلى وظائف أو طرق موجودة. تُطبَّق المُزيِّنات على الوظائف باستخدام صيغة @decorator_name.

# Basic example of a decorator
def my_decorator(func):
    def wrapper():
        print("Something is happening before the function is called.")
        func()
        print("Something is happening after the function is called.")
    return wrapper

@my_decorator
def say_hello():
    print("Hello!")

say_hello()

كيف تعمل الديكورات

عندما تقوم بتطبيق ديكور على دالة، يقوم Python بشكل أساسي بتنفيذ الخطوات التالية:

  1. يتم استدعاء دالة الديكور باستخدام الدالة الأصلية كحجة لها.
  2. تعرف وظيفة الديكور وظيفة جديدة (غالبًا ما تسمى wrapper) تعمل على تحسين أو تعديل سلوك الوظيفة الأصلية.
  3. تقوم دالة الديكور بإرجاع الدالة الجديدة.
  4. عندما يتم استدعاء الوظيفة المزخرفة، فإنها في الواقع تقوم باستدعاء الوظيفة الجديدة التي تم إرجاعها بواسطة المزخرف.

إنشاء ديكور بسيط

دعنا ننشئ مُزيِّنًا بسيطًا يقيس وقت تنفيذ إحدى الوظائف. وهذا مفيد لاختبار الأداء وتحسينه.

import time

def timing_decorator(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"Execution time: {end_time - start_time} seconds")
        return result
    return wrapper

@timing_decorator
def slow_function():
    time.sleep(2)
    print("Function finished!")

slow_function()

استخدام الديكورات مع الوسائط

في بعض الأحيان، قد ترغب في تمرير وسيطات إلى المزخرف الخاص بك. لتحقيق ذلك، تحتاج إلى إنشاء مصنع مزخرف - وهي دالة تعيد مزخرفًا. فيما يلي مثال لمزخرف يأخذ وسيطة لتحديد رسالة مخصصة.

def custom_message_decorator(message):
    def decorator(func):
        def wrapper(*args, **kwargs):
            print(message)
            return func(*args, **kwargs)
        return wrapper
    return decorator

@custom_message_decorator("Starting the function...")
def greet(name):
    print(f"Hello, {name}!")

greet("Alice")

مُزيِّنات للطرق في الفئات

يمكن أيضًا استخدام المزخرفات مع الأساليب داخل الفئات. تشمل الاستخدامات الشائعة تسجيل استدعاءات الأساليب والتحكم في الوصول وتخزين النتائج مؤقتًا. فيما يلي مثال لاستخدام مزخرف لتسجيل استدعاءات الأساليب في فئة.

def log_method_call(method):
    def wrapper(self, *args, **kwargs):
        print(f"Calling {method.__name__} with arguments {args} and keyword arguments {kwargs}")
        return method(self, *args, **kwargs)
    return wrapper

class MyClass:
    @log_method_call
    def my_method(self, x, y):
        print(f"Result: {x + y}")

obj = MyClass()
obj.my_method(5, 7)

زخارف السلسلة

يمكنك تطبيق عدة ديكورات على وظيفة واحدة. يتم تطبيقها من الديكور الداخلي إلى الديكور الخارجي. يتيح لك هذا تكوين وظائف مختلفة معًا. فيما يلي مثال لتسلسل ديكورين:

def uppercase_decorator(func):
    def wrapper(*args, **kwargs):
        result = func(*args, **kwargs)
        return result.upper()
    return wrapper

def exclamation_decorator(func):
    def wrapper(*args, **kwargs):
        result = func(*args, **kwargs)
        return result + "!"
    return wrapper

@exclamation_decorator
@uppercase_decorator
def greet(name):
    return f"Hello, {name}"

print(greet("Alice"))

خاتمة

تعتبر الديكورات أداة متعددة الاستخدامات في Python تتيح لك تحسين أو تعديل سلوك الوظائف والطرق. باستخدام الديكورات، يمكنك إضافة وظائف قابلة لإعادة الاستخدام عبر قاعدة التعليمات البرمجية الخاصة بك دون تغيير المنطق الأساسي للوظائف. سواء للتسجيل أو التوقيت أو تعديل الإخراج، تساعد الديكورات في الحفاظ على نظافة التعليمات البرمجية الخاصة بك وقابليتها للصيانة. تدرب على استخدام الديكورات لتصبح أكثر كفاءة والاستفادة من قوتها في مشاريع Python الخاصة بك.