2.11. Koşullular¶
Bir koşullu, yalnızca bir test doğru olarak değerlendirildiğinde bir kod bloğunu çalıştırır. Anahtar sözcük if‘tir; isteğe bağlı olarak bir veya daha fazla elif (“else if”) dalı ve son bir else izler.
n = 42
if n > 0:
print("positive")
elif n < 0:
print("negative")
else:
print("zero")
Her dalın gövdesi, onun altında girintilenmiş olan her şeydir (geleneksel olarak dört boşluk). Python, dalları sırayla dolaşır, testi doğru olan ilkini çalıştırır ve geri kalanını atlar. else bloğu yalnızca önceki her test yanlışsa çalışır; her zaman isteğe bağlıdır.
Yalnızca bir dal çalışır. Testler, biri başarılı olana kadar yukarıdan aşağıya değerlendirilir; geri kalanı atlanır.¶
2.11.1. Doğruluk değeri¶
Bir if içindeki bir testin True veya False döndürmesi gerekmez – herhangi bir değer doğru (truthy) ya da yanlış (falsy) olarak sayılır. Yanlış değerler şunlardır:
Diğer her şey doğrudur. Bu, derli toplu testler yazmanızı sağlar:
if name: # false on empty string
print("hello", name)
if items: # false on empty list, dict, etc.
process(items)
Doğruluk değerinin anlamı değiştirdiğine dikkat edin. if value:, if value is not None: ile aynı değildir – ilki ayrıca value, 0 veya "" olduğunda da yanlıştır. Gerçekten “bu tam olarak None mi” demek istediğinizde, açıkça is None / is not None kullanın.
2.11.2. Üçlü ifadeler¶
Bir koşullu, bir ifadenin içinde görünebilir:
label = "even" if n % 2 == 0 else "odd"
Şöyle okuyun: “n % 2 == 0 ise label, "even" değilse "odd" olur.” Tek satırlık ifadeler için kullanışlıdır; bir satırdan fazlası için tam bir if deyimi okumayı kolaylaştırır.
2.11.3. İç içe yerleştirme ve erken dönüşler¶
Koşullular keyfi olarak derin bir şekilde iç içe yerleştirilebilir, ancak her ek girinti katmanı bir fonksiyonu okumayı zorlaştırır. Aşağıdaki örnek, asıl işi yapmadan önce dört koşulu kontrol eder ve yararlı satırı dört girinti içine gömülü bırakır:
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
İki kalıp bu tür kodu düzleştirir.
2.11.3.1. Korumalar için erken dönüşler¶
Her “çık” durumunu önce, her biri kendi return ifadesiyle ele alın; böylece ana mantık dış girintide kalır. Her koruma şöyle okunur: “bu, ele aldığımız bir durum değil; çık”:
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)
“Ana yol” artık dört katman içinde gömülü değil, fonksiyonun altındaki tek bir satırdır. Bu stile bazen koruma cümlesi (guard clause) kalıbı denir.
2.11.3.2. Testleri and / or ile birleştirme¶
Aynı dal için birkaç koşulun tümünün geçerli olması gerektiğinde, bunları iç içe yerleştirmek yerine and ile birleştirin. Her biri bağımsız olarak dalı tetikleyen koşullar or ile birleşir:
# 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
Her iki biçim de kısa devre yapar, bu nedenle sağ taraftaki masraflı bir kontrol yalnızca soldaki daha ucuz kontroller soruyu zaten çözmemişse çalışır.