match-case – התאמת דפוסים
- Feb 3, 2019
- 2 min read
match-case – התאמת דפוסים
בגרסה 3.10 של פייתון נוספה פקודה חדשה ומאוד שימושית – match-case. מי שמכיר שפות תכנות אחרות אולי מזהה את הרעיון מפקודת switch שקיימת ב-C או ב-JavaScript, אבל ה-match של פייתון חזק הרבה יותר כי הוא יודע להתאים דפוסים (patterns) ולא רק ערכים פשוטים.
נתחיל מהדוגמה הבסיסית ביותר – התאמה לפי ערך –
def check_status(code): match code: case 200: return "הכל תקין" case 404: return "לא נמצא" case 500: return "שגיאת שרת" case _: return "קוד לא מוכר"
print(check_status(200))
print(check_status(404))
print(check_status(999))
>>>
הכל תקין
לא נמצא
קוד לא מוכר
הפקודה match בודקת את הערך של code ומשווה אותו לכל אחד מה-case. ה-case עם קו תחתון (_) הוא ברירת המחדל – הוא תופס הכל, כמו else.
אם חשבתם שזה סתם switch משודרג, חכו. match-case יודע להתאים גם מבנים (structures) – וזה מה שהופך אותו למיוחד באמת –
def describe_point(point): match point: case (0, 0): return "נקודת המקור" case (x, 0): return f"על ציר ה-X, בנקודה {x}" case (0, y): return f"על ציר ה-Y, בנקודה {y}" case (x, y): return f"נקודה ({x}, {y})"
print(describe_point((0, 0)))
print(describe_point((5, 0)))
print(describe_point((3, 7)))
>>>
נקודת המקור
על ציר ה-X, בנקודה 5
נקודה (3, 7)
שימו לב מה קרה כאן – פייתון לא רק בדק שוויון, הוא פירק את הטופל לחלקיו ובדק איזה חלקים שווים ל-0 ואיזה לא. המשתנים x ו-y נוצרו אוטומטית והתמלאו בערכים שנמצאו. זה נקרא destructuring – פירוק המבנה.
אפשר להוסיף תנאים (guards) עם if –
def check_age(person): match person: case {"name": name, "age": age} if age < 18: return f"{name} הוא קטין" case {"name": name, "age": age} if age >= 18: return f"{name} הוא בגיר"
print(check_age({"שם": "יוסי", "age": 15}))
print(check_age({"שם": "דנא", "age": 25}))
>>>
יוסי הוא קטין
דנא הוא בגיר
כאן match-case פירק מילון, שלף ממנו ערכים לפי מפתחות, ואז בדק תנאי נוסף עם if. המשתנים name ו-age נוצרו אוטומטית מתוך המילון.
אפשר גם לשלב כמה ערכים באותו case באמצעות הסימן | (or) –
def day_type(day): match day: case "שבת" | "ראשון": return "סוף שבוע" case "שני" | "שלישי" | "רביעי" | "חמישי" | "שישי": return "יום עבודה" case _: return "יום לא מוכר"
print(day_type("שבת"))
print(day_type("רביעי"))
>>>
סוף שבוע
יום עבודה
דוגמה מעשית – ניתוח פקודות מהמשתמש –
def handle_command(command): match command.split(): case ["quit"]: return "יוצא מהתוכנית" case ["hello", name]: return f"שלום {name}!" case ["add", x, y]: return f"התוצאה: {int(x) + int(y)}" case _: return "פקודה לא מוכרת"
print(handle_command("quit"))
print(handle_command("hello Eddie"))
print(handle_command("add 5 3"))
>>>
יוצא מהתוכנית
שלום Eddie!
התוצאה: 8
כאן match-case קיבל מחרוזת, פיצל אותה למילים עם split, ואז התאים את הרשימה שנוצרה לדפוסים שונים. אם המילה הראשונה היא hello ואחריה יש מילה אחת נוספת, המילה הזו נכנסת למשתנה name.
לסיכום – match-case הוא כלי חזק שמחליף שרשראות ארוכות של if-elif. הוא מתאים לא רק לערכים פשוטים אלא גם למבנים מורכבים כמו טופלים, רשימות ומילונים, עם אפשרות להוסיף תנאים. כדאי להכיר ולהשתמש.
Comments