מדריך למעצבי Python למתכנתים מתקדמים

מעצבי פייתון הם כלי רב עוצמה וגמיש לשינוי ההתנהגות של פונקציות או שיטות. הם מאפשרים למתכנתים להרחיב או לשנות את הפונקציונליות של אובייקטים הניתנים להתקשרות באופן נקי, קריא וניתן לתחזוקה. מאמר זה בוחן מושגים מתקדמים הקשורים למעצבי Python, כולל מעצבים מקוננים, טיעונים לקשטים ומעצבים מבוססי כיתה.

מה הם דקורטורים?

דקורטורים הם פונקציות שמשנות את ההתנהגות של פונקציה אחרת. הם עוטפים פונקציה נוספת כדי להרחיב את ההתנהגות שלה מבלי לשנות במפורש את הקוד שלה. מעצבים מוגדרים באמצעות התחביר @decorator_name וממוקמים מעל הגדרת הפונקציה.

תחביר דקורטור בסיסי

מעצב פשוט לוקח פונקציה כארגומנט, מגדיר פונקציה פנימית שמוסיפה התנהגות כלשהי, ואז מחזיר את הפונקציה הפנימית.

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()

דקורטור פונקציות עם טיעונים

מעצבים יכולים להיות גמישים יותר על ידי קבלת טיעונים. כדי ליצור דקורטור כזה צריך לכתוב פונקציה שמחזירה דקורטור. זה מאפשר הוספת התנהגות דינמית יותר למעצבים.

def repeat(num_times):
    def decorator_repeat(func):
        def wrapper(*args, **kwargs):
            for _ in range(num_times):
                func(*args, **kwargs)
        return wrapper
    return decorator_repeat

@repeat(num_times=3)
def greet(name):
    print(f"Hello, {name}!")

greet("Alice")

מקשטי קינון

ניתן לקנן מעצבים כדי לשלב התנהגויות מרובות. לדוגמה, אנו יכולים להשתמש בשני מעצבים או יותר בפונקציה אחת.

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

def repeat_decorator(func):
    def wrapper(*args, **kwargs):
        result = func(*args, **kwargs)
        return result + result
    return wrapper

@repeat_decorator
@uppercase_decorator
def say_word(word):
    return word

print(say_word("hello"))

מעצבים מבוססי כיתות

ב-Python, מעצבים יכולים להיות מיושמים גם כמחלקות באמצעות שיטת __call__. מעצבים מבוססי כיתות שימושיים כאשר אתה צריך ניהול והתנהגות מדינה מורכבים יותר.

class CountCalls:
    def __init__(self, func):
        self.func = func
        self.num_calls = 0

    def __call__(self, *args, **kwargs):
        self.num_calls += 1
        print(f"Call {self.num_calls} of {self.func.__name__!r}")
        return self.func(*args, **kwargs)

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

say_hello()
say_hello()

שימוש ב-functools.wraps כדי לשמור על מטא נתונים

כשאתה כותב מעצבים, הפונקציה המעוטרת מאבדת את המטא-נתונים המקוריים שלה, כגון השם והמחרוזת שלה. ניתן להשתמש במעצב functools.wraps כדי להעתיק את המטא-נתונים של הפונקציה המקורית לפונקציית העטיפה.

from functools import wraps

def my_decorator(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        print("Wrapper function executed before", func.__name__)
        return func(*args, **kwargs)
    return wrapper

@my_decorator
def display_info(name, age):
    """Displays name and age."""
    print(f"display_info ran with arguments ({name}, {age})")

print(display_info.__name__)  # Output: display_info
print(display_info.__doc__)   # Output: Displays name and age.

מַסְקָנָה

מעצבי Python הם תכונה רבת עוצמה המאפשרת עיצוב קוד גמיש ושינוי התנהגות. שימוש מתקדם, כגון מעצבים מקוננים, מעצבים עם ארגומנטים ומעצבים מבוססי כיתה, יכול לספק אפילו יותר פונקציונליות וקריאות לתוכניות Python. על ידי הבנה ושימוש נכון של מעצבים, מפתחים יכולים לכתוב קוד תמציתי, יעיל וקריא יותר.