2.23. מעטרים¶
מעטר (decorator) הוא תחביר שעוטף פונקציה (או מתודה) בפונקציה אחרת. העוטף יכול להוסיף התנהגות לפני ואחרי הקריאה המקורית, להחליף את ערך ההחזרה, או לצרף מטא-נתונים. הצורה היא:
@wrapper
def f():
...
השורה @wrapper שקולה ל-f = wrapper(f) – הפונקציה f נבנית כרגיל, אחר כך נמסרת ל-wrapper, והתוצאה נקשרת מחדש לשם f.
מעטר מקבל פונקציה ומחזיר פונקציה חדשה.¶
2.23.1. מעטרי מתודות מובנים¶
כמה מעטרים מגיעים עם Python ומשמשים בתוך גופי מחלקות.
2.23.1.1. @property¶
הופך מתודה לתכונה מחושבת. הקורא ניגש אליה כאילו הייתה תכונה רגילה (ללא סוגריים), אך מתודה רצה בכל קריאה:
class Circle:
def __init__(self, radius):
self.radius = radius
@property
def area(self):
return 3.14159 * self.radius * self.radius
c = Circle(5)
print(c.area) # 78.53975 -- no parentheses
השתמשו בו כאשר תכונה שנראית פשוטה זקוקה לחישוב קטן מאחוריה. אם העבודה יקרה, העדיפו מתודה רגילה – קוראים אינם מצפים שקריאות לתכונות יהיו איטיות.
2.23.1.2. @classmethod¶
מגדיר מתודה שמקבלת את המחלקה כארגומנט הראשון שלה במקום מופע. הפרמטר הראשון מקובל לקרוא לו cls:
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
@classmethod
def origin(cls):
return cls(0, 0)
p = Point.origin()
מתודות מחלקה הן הדרך הסטנדרטית לספק בנאים חלופיים – פונקציות יצרן שמחזירות מופע הבנוי בדרך שאינה ברירת המחדל.
2.23.1.3. @staticmethod¶
מגדיר מתודה שאינה מקבלת לא את המופע ולא את המחלקה – היא פשוט פונקציה רגילה השוכנת במרחב השמות של המחלקה מטעמים ארגוניים:
class Temperature:
@staticmethod
def c_to_f(c):
return c * 9 / 5 + 32
Temperature.c_to_f(100) # 212.0
השתמשו בו במשורה; אם לפונקציה באמת אין שום קשר למצב המחלקה, פונקציה רגילה ברמת המודול בדרך כלל נקייה יותר.
2.23.2. כתיבת מעטר מותאם אישית¶
מעטר הוא פונקציה שמקבלת פונקציה ומחזירה פונקציה. הצורה המינימלית:
def log_calls(func):
def wrapper(*args, **kwargs):
print("calling", func.__name__)
return func(*args, **kwargs)
return wrapper
@log_calls
def add(a, b):
return a + b
add(2, 3)
פלט:
calling add
ה-wrapper סוגר על func ומעביר אליו את הכל. *args / **kwargs מאפשרים לו לעבוד על כל פונקציה, לא רק על כאלה עם שני ארגומנטים. דפוס זה הוא היסוד של מעטרים מורכבים יותר (תזמון, מטמון, ניסיון-חוזר-בכשל) אך הליבה תמיד זהה: לקבל פונקציה, להחזיר פונקציה.