← Kursa Dön
📄 Text · 12 min

Boolean ve None

Programlama, karar vermekle ilgilidir. "Kullanıcı giriş yapmış mı?", "Bakiye yeterli mi?", "Dosya var mı?" — bu soruların hepsinin cevabı ya evet ya da hayır. İşte bool tipi tam da bu iş için var. Ve None? O da "cevap yok" durumunu temsil eder. Bu derste ikisini de derinlemesine öğreneceksin.


bool Tipi: True ve False

Python'da boolean (mantıksal) veri tipi sadece iki değer alabilir: True ve False. Büyük harfle başladığına dikkat et — true veya TRUE geçerli değil.

aktif = True
silindi = False

print(type(aktif))    # <class 'bool'>
print(type(silindi))  # <class 'bool'>

bool, int'in Alt Sınıfıdır

Çoğu kişinin bilmediği bir gerçek: Python'da bool, int'in alt sınıfıdır. True aslında 1, False aslında 0'dır.

print(isinstance(True, int))   # True — bool, int'in alt sınıfı
print(True == 1)    # True
print(False == 0)   # True

# Aritmetik işlemlerde kullanılabilir
print(True + True)        # 2
print(True + False)       # 1
print(True * 10)          # 10
print(False * 10)         # 0

# Sayma trick'i — True'ları say
sayilar = [3, 7, 2, 9, 1, 8, 4]
buyuk_sayisi = sum(x > 5 for x in sayilar)
print(f"5'ten büyük: {buyuk_sayisi}")  # 3

Bu, her True bir 1 olduğu için çalışır. sum() içinde her True bir 1 olarak toplanır.

# Pratik: doğru cevap yüzdesi
cevaplar = [True, False, True, True, False, True]
basari_orani = sum(cevaplar) / len(cevaplar)
print(f"Başarı: {basari_orani:.0%}")  # Başarı: 67%

Truthy ve Falsy Kavramı

Python'da sadece True ve False boolean değildir. Her değerin bir "doğruluk değeri" (truthiness) vardır. Bir değer koşul olarak kullanıldığında otomatik olarak boolean'a dönüştürülür.

Bunu bir ışık anahtarı gibi düşün. Elinde bir şey varsa ışık yanar (True). Elin boşsa ışık söner (False).

Falsy Değerler (False olarak değerlendirilenler)

# Bu değerlerin hepsi False olarak değerlendirilir
falsy_degerler = [
    False,      # bool False
    0,          # sıfır (int)
    0.0,        # sıfır (float)
    0j,         # sıfır (complex)
    "",         # boş string
    [],         # boş liste
    (),         # boş tuple
    {},         # boş dict
    set(),      # boş set
    None,       # None
    range(0),   # boş range
]

for deger in falsy_degerler:
    print(f"bool({str(deger):12s}) = {bool(deger)}")

Truthy Değerler (True olarak değerlendirilenler)

Falsy olmayan her şey truthy'dir:

# Bunların hepsi True olarak değerlendirilir
truthy_degerler = [
    True,           # bool True
    1,              # sıfır olmayan int
    -1,             # negatif sayılar da truthy
    3.14,           # sıfır olmayan float
    "merhaba",      # dolu string
    " ",            # boşluk bile truthy (boş değil çünkü)
    [1, 2],         # dolu liste
    {"a": 1},       # dolu dict
    (0,),           # dolu tuple (içi 0 olsa bile)
]

for deger in truthy_degerler:
    print(f"bool({str(deger):15s}) = {bool(deger)}")

Pratikte Kullanım

# ❌ Gereksiz karşılaştırma
if len(liste) > 0:
    print("Liste dolu")

if aktif == True:
    print("Aktif")

if isim != "":
    print("İsim var")

# ✅ Pythonic yol
if liste:
    print("Liste dolu")

if aktif:
    print("Aktif")

if isim:
    print("İsim var")
# Boş kontrolleri
def kullanici_bilgi(isim, email=None, telefon=None):
    print(f"İsim: {isim}")
    
    if email:
        print(f"E-posta: {email}")
    else:
        print("E-posta belirtilmemiş")
    
    if telefon:
        print(f"Telefon: {telefon}")
    else:
        print("Telefon belirtilmemiş")

kullanici_bilgi("Ali", email="ali@test.com")
# İsim: Ali
# E-posta: ali@test.com
# Telefon belirtilmemiş

⚠️ Dikkat: Truthy/Falsy kontrolü bazen beklenmedik sonuçlar verebilir. Mesela 0 falsy'dir — ama 0 geçerli bir değer olabilir (sıcaklık 0°C gibi). Böyle durumlarda açık karşılaştırma yap: if sicaklik is not None: gibi.

# Tuzak: 0 geçerli bir değer ama falsy
sicaklik = 0

# ❌ Yanlış — 0 derece de geçerli bir sıcaklık!
if sicaklik:
    print(f"Sıcaklık: {sicaklik}°C")
else:
    print("Sıcaklık bilgisi yok")  # Bu çalışır — yanlış!

# ✅ Doğru
if sicaklik is not None:
    print(f"Sıcaklık: {sicaklik}°C")  # Sıcaklık: 0°C
else:
    print("Sıcaklık bilgisi yok")

Karşılaştırma Operatörleri

Karşılaştırma operatörleri iki değeri karşılaştırır ve boolean (True veya False) döner.

OperatörAnlamıÖrnekSonuç
==Eşit mi?5 == 5True
!=Eşit değil mi?5 != 3True
<Küçük mü?3 < 5True
>Büyük mü?5 > 3True
<=Küçük veya eşit mi?5 <= 5True
>=Büyük veya eşit mi?3 >= 5False
x = 10
y = 20

print(x == y)    # False
print(x != y)    # True
print(x < y)     # True
print(x > y)     # False
print(x <= 10)   # True
print(x >= 20)   # False

Zincirleme Karşılaştırma (Chained Comparison)

Python, birden fazla karşılaştırmayı zincirleyebilir. Bu, diğer dillerin çoğunda olmayan harika bir özellik.

x = 15

# Zincirleme — çok okunaklı
print(10 < x < 20)     # True (x, 10 ile 20 arasında mı?)
print(1 <= x <= 100)    # True

# Diğer dillerde böyle yazmak gerekir:
print(10 < x and x < 20)  # True — aynı şey ama daha uzun

# Üçlü zincir bile olur
a, b, c = 1, 2, 3
print(a < b < c)        # True
print(a < b > c)        # False

# Eşitlik zinciri
print(1 == 1 == 1)      # True
print(1 == 1 == 2)      # False

Farklı Tipleri Karşılaştırma

# int ve float karşılaştırılabilir
print(1 == 1.0)     # True
print(1 < 1.5)      # True

# bool ve int karşılaştırılabilir (bool, int'in alt sınıfı)
print(True == 1)    # True
print(False == 0)   # True

# String karşılaştırma — leksikografik (Unicode sırasına göre)
print("apple" < "banana")   # True
print("abc" < "abd")        # True
print("A" < "a")            # True (A=65, a=97)

# Farklı tipler karşılaştırılamaz (< , > için)
# print("5" < 5)  # TypeError!
print("5" == 5)    # False — hata vermez ama False döner

Mantıksal Operatörler: and, or, not

Mantıksal operatörler boolean değerleri birleştirir.

and (Ve)

Her iki koşul da True olmalı:

yas = 25
gelir = 5000

if yas >= 18 and gelir >= 3000:
    print("Kredi onaylandı")

# Doğruluk tablosu
print(True and True)    # True
print(True and False)   # False
print(False and True)   # False
print(False and False)  # False

or (Veya)

En az bir koşul True olmalı:

gun = "Cumartesi"

if gun == "Cumartesi" or gun == "Pazar":
    print("Hafta sonu!")

# Doğruluk tablosu
print(True or True)     # True
print(True or False)    # True
print(False or True)    # True
print(False or False)   # False

not (Değil)

Boolean değeri tersine çevirir:

aktif = True
print(not aktif)     # False

giris_yapildi = False
if not giris_yapildi:
    print("Lütfen giriş yapın")

# Boş kontrolü
liste = []
if not liste:
    print("Liste boş")

Gerçekçi Örnek

def giris_kontrol(kullanici_adi, sifre, aktif_mi):
    if not kullanici_adi or not sifre:
        return "Kullanıcı adı ve şifre gerekli!"
    
    if not aktif_mi:
        return "Hesabınız aktif değil!"
    
    if len(sifre) < 8:
        return "Şifre en az 8 karakter olmalı!"
    
    return "Giriş başarılı!"

print(giris_kontrol("ali", "12345678", True))   # Giriş başarılı!
print(giris_kontrol("", "12345678", True))        # Kullanıcı adı ve şifre gerekli!
print(giris_kontrol("ali", "123", True))          # Şifre en az 8 karakter olmalı!
print(giris_kontrol("ali", "12345678", False))    # Hesabınız aktif değil!

Short-Circuit Evaluation (Kısa Devre Değerlendirme)

Python'un and ve or operatörleri "kısa devre" yapabilir — yani sonucu belirlemek için gerekli olmayan ifadeyi hiç değerlendirmez.

Bunu bir güvenlik kapısı gibi düşün. İlk kapıdan geçemediysen, ikinci kapıyı kontrol etmeye gerek yok.

and ile Kısa Devre

and operatöründe ilk değer False ise, ikinci değere bakmaya gerek yok — sonuç zaten False.

# İlk koşul False → ikinci koşul hiç çalışmaz
x = 0
if x != 0 and 10 / x > 2:  # 10/0 hatası olmaz!
    print("Koşul sağlandı")
else:
    print("x sıfır")  # Bu çalışır

# Güvenli erişim deseni
liste = []
if liste and liste[0] > 5:  # Boş liste → IndexError olmaz!
    print("İlk eleman 5'ten büyük")

or ile Kısa Devre

or operatöründe ilk değer True ise, ikinci değere bakmaya gerek yok — sonuç zaten True.

# İlk koşul True → ikinci koşul hiç çalışmaz
x = 10
if x > 5 or cok_pahali_fonksiyon():  # Bu fonksiyon çağrılmaz!
    print("Koşul sağlandı")

and ve or'un Gerçek Dönüş Değeri

İlginç bir bilgi: and ve or aslında True/False döndürmez — operandlardan birini döndürür!

# and: İlk falsy değeri veya son değeri döner
print(1 and 2 and 3)      # 3 (hepsi truthy → son değer)
print(1 and 0 and 3)      # 0 (ilk falsy değer)
print("" and "hello")     # "" (ilk falsy değer)

# or: İlk truthy değeri veya son değeri döner
print(0 or "" or "hello")  # "hello" (ilk truthy değer)
print(0 or "" or [])        # [] (hepsi falsy → son değer)
print(1 or 2)               # 1 (ilk truthy değer)

Varsayılan Değer Deseni

or operatörünün bu davranışı, varsayılan değer atamak için kullanılır:

# Kullanıcı isim girmemişse varsayılan kullan
isim = input("İsminiz: ") or "Anonim"

# Fonksiyon parametrelerinde
def selamla(isim=None):
    isim = isim or "Dünya"
    return f"Merhaba, {isim}!"

print(selamla())         # Merhaba, Dünya!
print(selamla("Ali"))    # Merhaba, Ali!

💡 İpucu: or ile varsayılan değer atamak yaygındır ama dikkatli ol. isim = isim or "Varsayılan" demek, isim boş string, 0 veya False olduğunda da varsayılanı kullanır. Eğer sadece None durumunu yakalamak istersen isim = isim if isim is not None else "Varsayılan" kullan.


None Nedir?

None, Python'un "hiçbir şey" değeridir. Bir değişkenin henüz bir değeri olmadığını veya bir fonksiyonun bir şey döndürmediğini belirtir.

None şunlardan farklıdır:

  • 0 (bir sayı — değeri var, o değer sıfır)

  • "" (bir string — değeri var, o değer boş metin)

  • False (bir boolean — değeri var, o değer yanlış)

  • [] (bir liste — değeri var, o değer boş bir koleksiyon)

None ise "değer yok, tanımsız, belirsiz" demektir.

# Farkları görelim
print(type(None))      # <class 'NoneType'>
print(type(0))         # <class 'int'>
print(type(""))        # <class 'str'>
print(type(False))     # <class 'bool'>

# Hepsi falsy ama farklı şeyler
print(None == 0)       # False
print(None == "")      # False
print(None == False)   # False
print(None == None)    # True

None Singleton'dır

Python'da sadece bir tane None nesnesi var. Her None referansı aynı nesneye işaret eder.

a = None
b = None

print(a is b)     # True — aynı nesne
print(id(a))      # 94567812345000
print(id(b))      # 94567812345000 — aynı id

None Kontrolü: is None Kullan!

None kontrolünde her zaman is operatörünü kullan, == değil.

x = None

# ✅ Doğru
if x is None:
    print("x None")

# ✅ Doğru
if x is not None:
    print("x None değil")

# ❌ Yanlış (çalışır ama doğru değil)
if x == None:
    print("x None")

Neden is kullanmalıyız? Çünkü == operatörü bir sınıf tarafından override edilebilir. Kötü niyetli veya hatalı bir __eq__ metodu None ile True dönebilir. Ama is operatörü override edilemez — her zaman gerçek kimlik karşılaştırması yapar.

# Bu sınıf her şeye "eşitim" der
class Tuhaf:
    def __eq__(self, other):
        return True

t = Tuhaf()
print(t == None)     # True — yanıltıcı!
print(t is None)     # False — güvenilir!

Fonksiyonlarda None

Default Return

Bir fonksiyon açıkça return ifadesi kullanmazsa veya return tek başına kullanılırsa, None döner.

def selamla(isim):
    print(f"Merhaba, {isim}!")
    # return yok → None döner

sonuc = selamla("Ali")
print(sonuc)       # None
print(type(sonuc)) # <class 'NoneType'>
# return tek başına da None döner
def ara_ve_dur(liste, hedef):
    for eleman in liste:
        if eleman == hedef:
            print(f"{hedef} bulundu!")
            return  # None döner
    print(f"{hedef} bulunamadı")
    # return yok → None döner

sonuc = ara_ve_dur([1, 2, 3], 2)
print(sonuc)  # None

None ile Parametre Yönetimi

Mutable default argument sorununu None ile çözmek yaygın bir desendir:

# ❌ Tehlikeli — mutable default argument
def eleman_ekle(deger, liste=[]):
    liste.append(deger)
    return liste

print(eleman_ekle(1))  # [1]
print(eleman_ekle(2))  # [1, 2] — Sürpriz!

# ✅ Güvenli — None kullan
def eleman_ekle(deger, liste=None):
    if liste is None:
        liste = []
    liste.append(deger)
    return liste

print(eleman_ekle(1))  # [1]
print(eleman_ekle(2))  # [2] — Beklenen davranış

Opsiyonel Dönüş Değeri

def kullanici_bul(kullanicilar, aranan_id):
    """Kullanıcıyı id ile bul, bulamazsa None döner"""
    for kullanici in kullanicilar:
        if kullanici["id"] == aranan_id:
            return kullanici
    return None  # Açıkça None dön

kullanicilar = [
    {"id": 1, "isim": "Ali"},
    {"id": 2, "isim": "Veli"},
    {"id": 3, "isim": "Ayşe"},
]

sonuc = kullanici_bul(kullanicilar, 2)
if sonuc is not None:
    print(f"Bulundu: {sonuc['isim']}")
else:
    print("Kullanıcı bulunamadı")

# Bulunamayan durum
sonuc = kullanici_bul(kullanicilar, 99)
if sonuc is None:
    print("Kullanıcı bulunamadı")  # Bu çalışır

bool() Fonksiyonu

bool() fonksiyonu herhangi bir değeri boolean'a çevirir:

# Falsy → False
print(bool(0))       # False
print(bool(""))      # False
print(bool([]))      # False
print(bool(None))    # False

# Truthy → True
print(bool(1))       # True
print(bool("a"))     # True
print(bool([0]))     # True (liste dolu, içeriği önemli değil)
print(bool(-1))      # True

# Özel sınıflarda __bool__ veya __len__
class Kutu:
    def __init__(self, icerik):
        self.icerik = icerik
    
    def __bool__(self):
        return len(self.icerik) > 0

bos_kutu = Kutu([])
dolu_kutu = Kutu([1, 2, 3])

print(bool(bos_kutu))   # False
print(bool(dolu_kutu))  # True

any() ve all() Fonksiyonları

any() ve all() fonksiyonları, bir koleksiyondaki truthy/falsy değerleri toplu olarak kontrol eder.

any() — Herhangi Biri True mu?

# En az bir True varsa True döner
print(any([False, False, True]))   # True
print(any([False, False, False]))  # False
print(any([]))                      # False (boş → False)

# Pratik kullanım
notlar = [45, 72, 38, 91, 55]
gecen_var_mi = any(n >= 50 for n in notlar)
print(f"Geçen öğrenci var mı? {gecen_var_mi}")  # True

# String kontrolü
sifre = "MyPassword123"
has_digit = any(c.isdigit() for c in sifre)
has_upper = any(c.isupper() for c in sifre)
has_lower = any(c.islower() for c in sifre)
print(f"Rakam: {has_digit}, Büyük: {has_upper}, Küçük: {has_lower}")

all() — Hepsi True mu?

# Hepsi True ise True döner
print(all([True, True, True]))    # True
print(all([True, False, True]))   # False
print(all([]))                     # True (boş → True, dikkat!)

# Pratik kullanım
notlar = [65, 72, 58, 91, 55]
hepsi_gecti_mi = all(n >= 50 for n in notlar)
print(f"Herkes geçti mi? {hepsi_gecti_mi}")  # True

# Form doğrulama
form = {
    "isim": "Ali",
    "email": "ali@test.com",
    "sifre": "12345678",
}
tum_alanlar_dolu = all(form.values())
print(f"Tüm alanlar dolu mu? {tum_alanlar_dolu}")  # True
# any ve all birlikte kullanım
ogrenciler = [
    {"isim": "Ali", "not": 85, "devam": True},
    {"isim": "Veli", "not": 45, "devam": True},
    {"isim": "Ayşe", "not": 92, "devam": False},
]

# Herkes devam etti mi?
print(all(o["devam"] for o in ogrenciler))  # False

# Herhangi biri 90+ aldı mı?
print(any(o["not"] >= 90 for o in ogrenciler))  # True

Pratik Örnekler

Güvenli Bölme

def guvenli_bolme(a, b):
    """Sıfıra bölme hatası olmadan bölme yapar"""
    if b == 0:
        return None
    return a / b

sonuc = guvenli_bolme(10, 3)
if sonuc is not None:
    print(f"Sonuç: {sonuc:.2f}")  # Sonuç: 3.33

sonuc = guvenli_bolme(10, 0)
if sonuc is None:
    print("Sıfıra bölünemez!")

Mantıksal İfade Değerlendirici

def erisim_kontrol(kullanici):
    """Kullanıcı erişim kontrolü"""
    # None kontrolü
    if kullanici is None:
        return "Kullanıcı bilgisi yok"
    
    # Gerekli alanlar var mı?
    if not kullanici.get("isim"):
        return "İsim eksik"
    
    if not kullanici.get("rol"):
        return "Rol tanımsız"
    
    # Yetki kontrolü
    yetkili_roller = ["admin", "moderator", "editor"]
    if kullanici["rol"] in yetkili_roller and kullanici.get("aktif", False):
        return f"{kullanici['isim']} erişim onaylandı"
    
    return f"{kullanici['isim']} erişim reddedildi"

# Test
print(erisim_kontrol(None))
print(erisim_kontrol({"isim": "Ali"}))
print(erisim_kontrol({"isim": "Ali", "rol": "admin", "aktif": True}))
print(erisim_kontrol({"isim": "Ali", "rol": "user", "aktif": True}))

Özet

  • `bool` tipi sadece True ve False değerlerini alır; int'in alt sınıfıdır (True == 1, False == 0).

  • Truthy/Falsy: 0, "", [], {}, NoneFalse; geri kalan her şey → True.

  • Short-circuit evaluation: and ilk falsy'de durur, or ilk truthy'de durur — bu, güvenli erişim ve varsayılan değer desenleri için kullanılır.

  • None "hiçbir şey" demektir — 0, "" ve False'dan farklıdır.

  • None kontrolünde `is None` kullan, == None değil — çünkü is override edilemez ve her zaman güvenilirdir.

  • Fonksiyonlar açıkça return kullanmazsa None döner.