7.1 דקורטורים מתקדמים הרצאה
הקדמה¶
- בהרצאה נלמד איך לבנות decorator-ים מתקדמים בפייתון. לפני שאתם מתקדמים בשיעור, עברו שוב בסיכומים על מה למדנו על דקורטורים וודאו שאתם יודעים לכתוב דקורטור פשוט.
חזרה קצרצרה¶
- איך דקורטור עובד מאחורי הקלעים?
- דקורטור היא פונקציה שמטרתה לקשט פונקציות אחרות, דקורטור מקבל פונקציה כפרמטר, ומחזיר פונקציה מקושטת.
- הנה דוגמה לדקורטור, ניתן לראות שהדקורטור קיבל פונקציה כפרמטר, הגדיר פונקציה חדשה בתוכו, והחזיר את הפונקציה החדשה שהגדיר.
- אנחנו משתמשים באופרטור "@" בפייתון כדי לקשט את הפונקציות, אבל איך הקסם הזה עובד מאחורי הקלעים? כשאנחנו כותבים את הקוד הבא:
- הוא מתורגם לקוד הבא:
- הפונקצית דקורטור מקבלת כפרמטר את הפונקציה שאותה אנחנו מקשטים, הביטוי הזה מחזיר את הפונקציה המקשוטת ולה אנחנו מעבירים את הפרמטר "5" ומריצים.
דקורטור כפול¶
- אנחנו יכולים להכיל מספר של דקורטורים על פונקציה
def log(func): def wrapper(*args): print(f"function {func.__name__} started to run!") res = func(*args) print(f"function {func.__name__} finished!") return res return wrapper def twice(func): def wrapper(*args): res = func(*args) res = func(*args) return res return wrapper @log @twice def func(x): print("nice") print(x) func(5)
שני הדקורטורים יכולו על הפונקציה, קודם כל log ואז twice. - למה זה יתורגם?
פרמטר לדקורטור¶
- לפעמים נרצה לכתוב דקורטור שיכול לקבל פרמטר, זה יראה כך:
- למה שנרצה לעשות דקורטור כזה? אנחנו לא ממש, אני לא ראיתי את זה הרבה בשימוש בפייתון - אבל השאירו את האופציות פתוחות.
- במקרה הזה המטרה של הדקורטור זה לתת ערך לפרמטר הראשון של הפונקציה, בדוגמה למעלה הוא יביא לו 2.
- כך ניצור דקורטור כזה:
- חשבו על זה שבמקרה הזה הדקורטור שלנו מחזיר דקורטור, יצרנו דקורטור לדקורטורים.
-
הדקורטור הראשון מקבל את הפרמטר של הדקורטור, והדקורטור השני הוא הדקורטור של הפונקציה.
-
למה זה יתורגם?
- זה נראה קצת מסובך, אבל שימו לב שזה לא קריטי בכלל לזכור בדיוק איך זה עובד, חשוב שתזכרו שפרמטרים לדקורטורים זה דבר בפייתון, ואתם אולי תפגשו את זה בעתיד.
דקורטור כקלאס¶
- נוכל ליצור דקורטור עם
class, איך זה עובד? אנחנו יכולים לממש את המתודות:__init__, ו -__call__.
כך יראה המימוש:
- אחרכך נוכל להשתמש בזה ממש כמו דקורטור רגיל לחלוטין:
- למה זה יתורגם? (ספוילר: בדיוק כמו דקורטור רגיל)
- שימו לב שהדקורטור מקבל כפרמטר את הפונקציה, ואז עושה call לאובייקט שנוצר. שזה ממש תואם את הפונקציות
__init__ו -__call__שמימשנו, כאשר__init__נקרא בחלק הזה:MyDocrator(my_function)ומחזיר את אובייקט ואז__call__נקרא שאנחנו קוראים לאובייקט -("hello")
דקורטור לקלאס¶
כמו שאפשר לכתוב דקורטור לפונקציה, אפשר לכתוב דקורטור לקלאס.
- דקורטור לקלאס זה דקורטור שמקבל קלאס כפרמטר ומחזיר קלאס חדשה. הנה דוגמה לדקורטור כזה:
def add_method(cls):
"""
This decorator adds a new method to the decorated class.
"""
def new_method(self, x, y):
"""
This method adds two numbers.
"""
return x + y
# Adding the new method to the class
cls.new_method = new_method
return cls
- הדקורטור הזה מקבל קלאס, מוסיף לה פונקציה חדשה ומחזיר את הקלאס.
דוגמה לשימוש בדקורטור על קלאס:
@add_method
class Calculator:
def __init__(self):
pass
def multiply(self, x, y):
"""
This method multiplies two numbers.
"""
return x * y
# Creating an instance of the Calculator class
calc = Calculator()
# Using the added method
print(calc.new_method(3, 4)) # Output: 7
print(calc.multiply(3, 4)) # Output: 12