2.11. תנאים¶
תנאי מריץ בלוק קוד רק כאשר בדיקה מסוימת מוערכת כאמת. מילת המפתח היא if, ואחריה אופציונלית ענף elif (”else if“) אחד או יותר ו-else סופי.
n = 42
if n > 0:
print("positive")
elif n < 0:
print("negative")
else:
print("zero")
גוף כל ענף הוא כל מה שמוזח תחתיו (ארבעה רווחים לפי המוסכמה). Python עובר על הענפים לפי הסדר, מריץ את הראשון שבדיקתו אמת, ומדלג על השאר. בלוק ה-else רץ רק אם כל בדיקה קודמת הייתה שקר; הוא תמיד אופציונלי.
תמיד רץ ענף אחד בלבד. הבדיקות מוערכות מלמעלה למטה עד שאחת מצליחה; השאר מדולגים.¶
2.11.1. אמיתיוּת (Truthiness)¶
בדיקה ב-if אינה חייבת להחזיר True או False – כל ערך נחשב כ-אמיתי (truthy) או כ-שקרי (falsy). הערכים השקריים הם:
כל השאר אמיתי. הדבר מאפשר לכם לכתוב בדיקות תמציתיות:
if name: # false on empty string
print("hello", name)
if items: # false on empty list, dict, etc.
process(items)
שימו לב שאמיתיות משנה את המשמעות. if value: אינו זהה ל-if value is not None: – הראשון הוא גם שקר כאשר value הוא 0 או "". כאשר אתם באמת מתכוונים ”האם זה בדיוק None”, השתמשו ב-is None / is not None במפורש.
2.11.2. ביטויים טרנריים¶
תנאי יכול להופיע בתוך ביטוי:
label = "even" if n % 2 == 0 else "odd"
קראו כ-“label הוא "even" אם n % 2 == 0 אחרת "odd".“ שימושי לשורות בודדות; עבור כל דבר שמעבר לשורה אחת, הוראת if מלאה קלה יותר לקריאה.
2.11.3. קינון והחזרות מוקדמות¶
תנאים יכולים להתקנן עמוק באופן שרירותי, אך כל שכבת הזחה נוספת הופכת פונקציה לקשה יותר לקריאה. הדוגמה שלהלן בודקת ארבעה תנאים לפני ביצוע העבודה האמיתית ומשאירה את השורה השימושית קבורה ארבע הזחות פנימה:
def process(item):
if item is not None:
if item.is_valid():
if item.size() > 0:
if item.owner == "me":
return do_the_work(item)
return None
שני דפוסים משטחים קוד מסוג זה.
2.11.3.1. החזרות מוקדמות עבור שומרים¶
טפלו תחילה בכל מקרה של ”יציאה מוקדמת“, כל אחד עם ה-return משלו, כך שהלוגיקה הראשית נשארת בהזחה החיצונית. כל שומר נקרא כ-”זה אינו מקרה שאנו מטפלים בו; צא“:
def process(item):
if item is None:
return None
if not item.is_valid():
return None
if item.size() == 0:
return None
if item.owner != "me":
return None
return do_the_work(item)
”הנתיב הראשי“ הוא כעת שורה אחת בתחתית הפונקציה, לא קבור בתוך ארבע שכבות. סגנון זה נקרא לעיתים דפוס פסוקית השומר (guard clause).
2.11.3.2. שילוב בדיקות עם and / or¶
כאשר כמה תנאים חייבים כולם להתקיים עבור אותו ענף, שלבו אותם עם and במקום לקנן. תנאים שכל אחד מהם מפעיל את הענף באופן עצמאי משולבים עם or:
# all must hold -- use `and`
if user.is_admin() and user.has_permission("write") and not locked:
save()
# any one of them is enough -- use `or`
if c == " " or c == "\t" or c == "\n":
whitespace_count += 1
שתי הצורות מבצעות קיצור מעגל (short-circuit), כך שבדיקה יקרה בצד ימין רצה רק כאשר הבדיקות הזולות יותר משמאל עדיין לא הכריעו את השאלה.