ديكوريتورز في Python: ما هي وكيف تعمل ولماذا تستخدم

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

ما هي ديكوريتورز في Python

إذا كنت قد كتبت كودًا بلغة Python لأكثر من أسبوع، فبالتأكيد رأيت الرمز @ فوق دالة. هذا هو الـ decorator — أداة برمجية قوية وسهلة الفهم.

الديكوريتورز في Python تسمح لك بـ "تغليف" دالة داخل دالة أخرى. فهي تغير أو توسع سلوك الدالة دون تعديل الكود الأصلي. تُستخدم الديكوريتورز في كل مكان: في Flask، Django، FastAPI، pytest، وحتى في المكتبة القياسية للغة Python.

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

أساسيات الديكوريتورز

الديكوريتور هو دالة تستقبل دالة أخرى وتعيد دالة جديدة أو معدلة.

def decorator(func):
    def wrapper():
        print("قبل الاستدعاء")
        func()
        print("بعد الاستدعاء")
    return wrapper

@decorator
def say_hello():
    print("مرحبًا!")

say_hello()

نتيجة التنفيذ:

قبل الاستدعاء
مرحبًا!
بعد الاستدعاء

الرمز @decorator هو مجرد اختصار نحوي للكتابة التالية:

say_hello = decorator(say_hello)

البنية الداخلية للديكوريتورز

لفهم الديكوريتورز في Python، يجب أن تعرف المفاهيم الأساسية التالية:

  • في Python، الدوال هي كائنات من الدرجة الأولى
  • يمكن تمرير الدوال كوسائط لدوال أخرى
  • يمكن تعريف دوال داخل دوال أخرى
  • توجد آلية الإغلاق (closure)

النمط العام للديكوريتور

النمط الأدنى للديكوريتور يكون كالتالي:

def decorator(func):
    def wrapper(*args, **kwargs):
        # إجراءات قبل تنفيذ الدالة
        result = func(*args, **kwargs)
        # إجراءات بعد تنفيذ الدالة
        return result
    return wrapper

أمثلة عملية على الديكوريتورز

ديكوريتور قياس وقت التنفيذ

import time

def timing(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        execution_time = time.time() - start
        print(f"استغرقت {func.__name__} {execution_time:.4f} ثانية")
        return result
    return wrapper

@timing
def slow_func():
    time.sleep(1)
    return "تمت العملية"

slow_func()

هذا الديكوريتور مفيد لقياس أداء الدوال وتحسين الكود.

ديكوريتور التحقق من الصلاحية

def require_admin(func):
    def wrapper(user, *args, **kwargs):
        if user != "admin":
            raise PermissionError("الوصول ممنوع")
        return func(user, *args, **kwargs)
    return wrapper

@require_admin
def delete_database(user):
    print("تم حذف قاعدة البيانات!")
    return True

delete_database("admin")  # تنفيذ ناجح

هذا الديكوريتور يعزز أمان التطبيق من خلال التحكم في الوصول إلى الدوال الحساسة.

ديكوريتور تسجيل العمليات

import logging
from functools import wraps

def log_calls(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        logging.info(f"استدعاء الدالة {func.__name__} بالوسائط {args}, {kwargs}")
        try:
            result = func(*args, **kwargs)
            logging.info(f"تم تنفيذ الدالة {func.__name__} بنجاح")
            return result
        except Exception as e:
            logging.error(f"خطأ في الدالة {func.__name__}: {e}")
            raise
    return wrapper

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

إنشاء مصنع للديكوريتورز

عندما يحتاج الديكوريتور إلى استقبال معاملات، يتم إنشاء مصنع للديكوريتورز:

def repeat(n):
    def decorator(func):
        def wrapper(*args, **kwargs):
            results = []                

المدونات

توصيات الكتب