מדריך למעצבי 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. על ידי הבנה ושימוש נכון של מעצבים, מפתחים יכולים לכתוב קוד תמציתי, יעיל וקריא יותר.