2.15. ארגומנטים

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

2.15.1. ארגומנטים מיקומיים וארגומנטים לפי מילת מפתח

הקריאה הפשוטה ביותר מעבירה ארגומנטים לפי מיקום – הערך הראשון הולך לפרמטר הראשון, השני לשני, וכן הלאה:

def rect(x, y, w, h):
    return (x, y, w, h)

rect(10, 20, 100, 50)

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

rect(x=10, y=20, w=100, h=50)

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

rect(10, 20, w=100, h=50)         # OK
rect(x=10, 20, 100, 50)           # SyntaxError

2.15.2. ערכי ברירת מחדל

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

def greet(name, greeting="hello"):
    print(greeting, name)

greet("Alice")                    # hello Alice
greet("Alice", "hi")              # hi Alice
greet("Alice", greeting="hey")    # hey Alice

פרמטרים עם ערכי ברירת מחדל חייבים לבוא אחרי פרמטרים ללא ערכי ברירת מחדל בשורת ה-def.

אזהרה

ערכי ברירת המחדל מחושבים פעם אחת, כאשר ה-def רץ – לא בכל קריאה. שימוש בברירת מחדל ניתנת לשינוי ([], {}) גורם לכך שאותו אובייקט משותף בין כל הקריאות שלוקחות את ברירת המחדל. השתמשו ב-None כמסמן (sentinel) במקום זאת:

def append_to(item, target=None):
    if target is None:
        target = []
    target.append(item)
    return target

2.15.3. אורך משתנה: *args ו-**kwargs

פרמטר עם הקידומת * אוסף את כל הארגומנטים המיקומיים הנותרים לתוך tuple. פרמטר עם הקידומת ** אוסף את כל ארגומנטי מילות המפתח הנותרים לתוך dict. השמות המקובלים הם args ו-kwargs, אך כל מזהה עובד:

def report(label, *values, **options):
    print(label, values, options)

report("temps", 21, 22, 23, unit="C", precision=1)

פלט:

temps (21, 22, 23) {'unit': 'C', 'precision': 1}

פונקציה רק לעיתים נדירות זקוקה לשניהם. השימוש הנפוץ ביותר הוא העברת ארגומנטים ממעטפת לקריאה פנימית:

def log_and_call(func, *args, **kwargs):
    print("calling", func.__name__)
    return func(*args, **kwargs)

תחביר תמונת-המראה באתר הקריאה מפרק איטרבל לארגומנטים מיקומיים (*) או dict לארגומנטים לפי מילת מפתח (**):

point = (10, 20, 100, 50)
rect(*point)                      # same as rect(10, 20, 100, 50)

kwargs = {"x": 10, "y": 20, "w": 100, "h": 50}
rect(**kwargs)                    # same as rect(x=10, y=20, ...)

2.15.4. פרמטרים לפי מילת מפתח בלבד

* בפני עצמו ברשימת הפרמטרים (לא מחובר לשם) מסמן כל פרמטר שבא אחריו כמילת-מפתח-בלבד – הקורא חייב להשתמש בשם:

def crop(buffer, *, x, y, w, h):
    ...

crop(buffer, x=0, y=0, w=100, h=100)   # OK
crop(buffer, 0, 0, 100, 100)           # TypeError

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