🌐 Detecting your location…
📢 Advertisement — Configure AdSense in Appearance → Customize → AdSense Settings

الدليل الكامل لمصممي Python 2026: الأنماط والتخزين المؤقت واستخدام الإنتاج

⏱️4 min read  ·  864 words

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

ما هو الديكور؟

المزخرف هو دالة تغلف دالة أخرى لإضافة سلوك. ال@بناء الجملة هو السكر النحوي:

# These two are equivalent:

@my_decorator
def my_function():
    pass

# Same as:
def my_function():
    pass
my_function = my_decorator(my_function)

# Simple decorator example
def log_calls(func):
    def wrapper(*args, **kwargs):
        print(f"Calling {func.__name__}")
        result = func(*args, **kwargs)
        print(f"Done {func.__name__}")
        return result
    return wrapper

@log_calls
def greet(name: str) -> str:
    return f"Hello, {name}!"

greet("Alice")
# Calling greet
# Done greet

functools.wraps — الحفاظ على البيانات الوصفية

import functools

def my_decorator(func):
    @functools.wraps(func)  # preserves __name__, __doc__, __annotations__
    def wrapper(*args, **kwargs):
        return func(*args, **kwargs)
    return wrapper

@my_decorator
def add(a: int, b: int) -> int:
    return a + b

print(add.__name__)   # "add" (without wraps, would be "wrapper")
print(add.__doc__)    # preserved docstring

ديكور مع الحجج

import functools, time

# Decorator that accepts arguments uses three levels of nesting
def retry(max_attempts: int = 3, delay: float = 1.0, exceptions: tuple = (Exception,)):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            last_error = None
            for attempt in range(1, max_attempts + 1):
                try:
                    return func(*args, **kwargs)
                except exceptions as e:
                    last_error = e
                    if attempt < max_attempts:
                        print(f"Attempt {attempt} failed: {e}. Retrying in {delay}s...")
                        time.sleep(delay)
            raise last_error
        return wrapper
    return decorator

@retry(max_attempts=3, delay=0.5, exceptions=(ConnectionError, TimeoutError))
def fetch_data(url: str) -> dict:
    import requests
    return requests.get(url, timeout=5).json()

مصممو الديكور على أساس الفصل

import functools
import time
from collections import defaultdict

class RateLimit:
    def __init__(self, calls: int, period: float):
        self.calls = calls
        self.period = period
        self._call_times: list[float] = []

    def __call__(self, func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            now = time.time()
            # Remove calls older than period
            self._call_times = [t for t in self._call_times if now - t < self.period]

            if len(self._call_times) >= self.calls:
                wait_time = self.period - (now - self._call_times[0])
                if wait_time > 0:
                    time.sleep(wait_time)

            self._call_times.append(time.time())
            return func(*args, **kwargs)
        return wrapper

@RateLimit(calls=5, period=1.0)   # max 5 calls per second
def api_request(endpoint: str) -> dict:
    import requests
    return requests.get(f"https://api.example.com{endpoint}").json()

التخزين المؤقت للديكور

from functools import lru_cache, cache
import time

# Simple memoization (Python 3.9+)
@cache   # unlimited cache size
def fibonacci(n: int) -> int:
    if n < 2:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

# LRU cache with size limit
@lru_cache(maxsize=128)
def expensive_computation(x: float, y: float) -> float:
    time.sleep(0.1)  # simulate slow computation
    return x ** 2 + y ** 2

# Cache with expiry (custom implementation)
def ttl_cache(ttl_seconds: float):
    def decorator(func):
        cache_store: dict = {}
        cache_times: dict = {}

        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            key = (args, tuple(sorted(kwargs.items())))
            now = time.time()

            if key in cache_store and (now - cache_times[key]) < ttl_seconds:
                return cache_store[key]  # return cached

            result = func(*args, **kwargs)
            cache_store[key] = result
            cache_times[key] = now
            return result
        return wrapper
    return decorator

@ttl_cache(ttl_seconds=60)
def get_exchange_rate(currency: str) -> float:
    # Fetches rate from API, cached for 60 seconds
    ...

# Inspect cache stats
print(fibonacci.cache_info())  # CacheInfo(hits=5, misses=10, maxsize=None, currsize=10)
fibonacci.cache_clear()

الديكور في FastAPI

from fastapi import FastAPI, Depends, HTTPException, Request
from functools import wraps
import time

app = FastAPI()

# FastAPI uses decorators for routing
@app.get("/users/{user_id}")
async def get_user(user_id: int):
    return {"id": user_id}

# Custom decorator for timing API endpoints
def measure_time(func):
    @wraps(func)
    async def wrapper(*args, **kwargs):
        start = time.perf_counter()
        response = await func(*args, **kwargs)
        duration = time.perf_counter() - start
        print(f"{func.__name__}: {duration*1000:.2f}ms")
        return response
    return wrapper

@app.get("/expensive")
@measure_time
async def expensive_endpoint():
    import asyncio
    await asyncio.sleep(0.1)
    return {"status": "done"}

# Require auth decorator
def require_auth(func):
    @wraps(func)
    async def wrapper(request: Request, *args, **kwargs):
        token = request.headers.get("Authorization", "").replace("Bearer ", "")
        if not token or not validate_token(token):
            raise HTTPException(status_code=401, detail="Unauthorized")
        return await func(request, *args, **kwargs)
    return wrapper

أنماط الديكور الشائعة

import functools, time, logging

logger = logging.getLogger(__name__)

# Timing decorator
def timer(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        start = time.perf_counter()
        result = func(*args, **kwargs)
        elapsed = time.perf_counter() - start
        logger.debug(f"{func.__name__} took {elapsed*1000:.2f}ms")
        return result
    return wrapper

# Validation decorator
def validate_positive(func):
    @functools.wraps(func)
    def wrapper(value: float, *args, **kwargs):
        if value < 0:
            raise ValueError(f"Expected positive number, got {value}")
        return func(value, *args, **kwargs)
    return wrapper

# Singleton decorator
def singleton(cls):
    instances = {}
    @functools.wraps(cls)
    def get_instance(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    return get_instance

@singleton
class DatabaseConnection:
    def __init__(self, url: str):
        self.url = url

# Deprecation warning
def deprecated(reason: str = ""):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            import warnings
            msg = f"{func.__name__} is deprecated. {reason}"
            warnings.warn(msg, DeprecationWarning, stacklevel=2)
            return func(*args, **kwargs)
        return wrapper
    return decorator

@deprecated("Use new_function() instead")
def old_function():
    pass

التراص الديكور

# Decorators apply bottom-to-top
@retry(max_attempts=3)
@timer
@validate_positive
def compute(value: float) -> float:
    return value ** 2

# Equivalent to:
compute = retry(max_attempts=3)(timer(validate_positive(compute)))

تعد أدوات تزيين Python هي الطريقة الأنظف لإضافة اهتمامات شاملة مثل التسجيل والتخزين المؤقت وتحديد المعدل والمصادقة وإعادة المحاولة المنطقية دون تعديل الوظيفة الأساسية. استخدم دائما@functools.wrapsللحفاظ على البيانات الوصفية. أنشئ ديكورات ذات معلمات عندما تحتاج إلى سلوك قابل للتكوين.

✍️ Leave a Comment

Your email address will not be published. Required fields are marked *

🌐 Read in:🇬🇧 English🇩🇪 Deutsch🇧🇷 Português🇸🇦 العربية🇮🇳 हिन्दी🇧🇩 বাংলা