Python fonksiyonları çoğunlukla üç nedenle None döndürür: Fonksiyonda hiç return bulunmaması, sonucun yalnızca print() ile ekrana yazdırılması veya koşullu dalların bazı bölümlerinde return unutulması. Yani fonksiyon çağrısı çalışmış olabilir; ancak çağıran koda aktarılacak bir sonuç üretilmeden sona ermiştir.
İlk teşhis sorusu şudur: Fonksiyon çağrısının sonucu gerçekten bir değere atanıyor mu? Atama yapıldığı hâlde değişkende None görüyorsan, önce fonksiyonun bütün akış yollarını ve return ifadelerini kontrol et.
Python fonksiyonu neden None döndürür?
Python’da bir fonksiyon açıkça başka bir değer döndürmeden tamamlanırsa, çağrının sonucu None olur. Bu durum tek başına bir sözdizimi hatası değildir; Python, fonksiyonun sonuç üretmeden bittiğini ifade etmek için None değerini kullanır.
Örneğin aşağıdaki fonksiyonda işlem yapılır, fakat hesaplanan değer çağıran koda gönderilmez:
def kare_al(sayi):
sonuc = sayi * sayi
deger = kare_al(4)
print(deger) # None
Buradaki temel sorun return sonuc satırının eksik olmasıdır. Benzer şekilde, sonuç yalnızca print() ile gösteriliyorsa ekranda doğru değeri görsen bile fonksiyonun sonucu yine None olabilir.
Üçüncü yaygın belirti, koşullu dalların yalnızca bir kısmında değer döndürülmesidir. Örneğin indirim oranı yalnızca belirli bir tutarın üzerindeyse hesaplanıyor, diğer durumda hiçbir şey döndürülmüyorsa bazı çağrılar None üretir. Bu nedenle yalnızca “return var mı?” sorusunu değil, her olası yolun bir sonuçla bitip bitmediğini de kontrol etmek gerekir.
print() ile return arasındaki fark nasıl anlaşılır?

print() bir değeri kullanıcıya veya geliştiriciye ekranda gösterir. return ise değeri fonksiyonun çağrıldığı yere aktarır. Bu farkı aynı işlemi yapan iki fonksiyonla görebilirsin:
def yazdir_toplam(a, b):
print(a + b)
def dondur_toplam(a, b):
return a + b
ilk_sonuc = yazdir_toplam(3, 4)
ikinci_sonuc = dondur_toplam(3, 4)
print(ilk_sonuc) # Önce 7 yazılır, ardından None
print(ikinci_sonuc) # 7
yazdir_toplam() çağrısı sırasında 7 ekranda görünür; ancak bu değer ilk_sonuc değişkenine aktarılmaz. Bu yüzden ilk_sonuc ile matematiksel işlem yapmaya çalışmak beklenen sonucu vermez:
sonuc = yazdir_toplam(3, 4)
toplam = sonuc + 2 # TypeError: None ile sayı toplanamaz
return kullanıldığında ise dönen değer başka işlemlerde kullanılabilir ve fonksiyon çağrıları zincirlenebilir:
def ikiyle_carp(sayi):
return sayi * 2
def bir_ekle(sayi):
return sayi + 1
sonuc = bir_ekle(ikiyle_carp(5))
print(sonuc) # 11
| Belirti | Gerçek neden | Teşhis adımı | Çözüm |
|---|---|---|---|
Ekranda değer var, değişkende None var |
Yalnızca print() kullanılmış |
Çağrıyı bir değişkene ata ve değişkeni yazdır | return ile değeri gönder |
None ile toplama yapılırken TypeError |
Fonksiyon sonuç döndürmeden bitmiş | Tüm return satırlarını ve çağrı zincirini incele |
Beklenen değeri açıkça döndür |
Bazı girdiler çalışıyor, bazıları None veriyor |
Koşullu dallardan birinde return eksik |
Farklı girişlerle her dalı test et | Her dalı değer döndürecek biçimde tamamla |
Bu ayrımı pekiştirmek ve temel Python mantığını ölçmek için Python ve algoritmik düşünme bilgi testlerini çözebilirsin.
Koşullu dallarda eksik return nasıl bulunur?
Bir fonksiyonda if, elif ve else dalları varsa her olası akışın sonunda bir değer döndürülüp döndürülmediğini kontrol etmelisin. Bazı dallarda return bulunmuyorsa Python, fonksiyon o dala ulaştığında otomatik olarak None döndürür.
def indirimli_fiyat(tutar, uye):
if uye:
return tutar * 0.90
elif tutar >= 1000:
return tutar * 0.95
Bu fonksiyonda iki dalda değer döndürülüyor; ancak hiçbir koşulun karşılanmadığı durum için bir else dalı bulunmuyor. Farklı girdileri adım adım inceleyelim:
indirimli_fiyat(500, True):uyekoşulu sağlanır, ilk dal çalışır ve450.0döner.indirimli_fiyat(1200, False): İlk koşul sağlanmaz,tutar >= 1000koşulu sağlanır ve1140.0döner.indirimli_fiyat(500, False): İlk iki koşul da sağlanmaz. Fonksiyonun çalışacağı başka bir dal kalmadığı için sonuçNoneolur.
Teşhis sırasında yalnızca koşulların doğru yazılıp yazılmadığına değil, her koşulun sonunda fonksiyonun dışarıya ne aktardığına bak. İndirimsiz durumda tutarın kendisi kullanılacaksa eksik akış bir else ile tamamlanabilir:
def indirimli_fiyat(tutar, uye):
if uye:
return tutar * 0.90
elif tutar >= 1000:
return tutar * 0.95
else:
return tutar
else kullanmak, diğer koşulların dışında kalan girdiler için güvenli ve açık bir varsayılan sonuç tanımlamak anlamına gelir. Ancak her dalın sonucu farklı bir kurala göre belirleniyorsa varsayılan değeri rastgele seçmek yerine iş kuralını netleştirmelisin.
Sipariş indirimi fonksiyonunda None teşhis akışı

Şimdi tek bir sipariş fonksiyonu üzerinden ilerleyelim. Hatalı örnekte indirim uygulanmayan dal yalnızca ekrana bilgi yazıyor:
def siparis_indirimi(tutar):
if tutar >= 1000:
return tutar * 0.90
else:
print("İndirim uygulanmadı.")
sonuc = siparis_indirimi(500)
print("Ödenecek tutar:", sonuc)
Ekranda önce İndirim uygulanmadı., ardından Ödenecek tutar: None görülür. Çünkü print() mesajı ekrana gösterir; çağıran koda bir sonuç aktarmaz. İlk teşhis adımı, fonksiyon çağrısını bir değişkene atayıp bu değişkeni gözlemlemektir. Sonra gövdede return ifadelerini ara ve hangi dallarda bulunduğunu kontrol et.
Karar çerçevesi olarak şu dört soruyu kullanabilirsin: Sonuç nerede üretiliyor? Kime aktarılıyor? Her akışta aktarılıyor mu? Sonuç daha sonra nasıl kullanılıyor? Bu örnekte sonuç ilk dalda üretilip çağırana aktarılıyor; indirimsiz dalda ise yalnızca mesaj yazılıyor. Sonuç ödeme hesabında kullanılacağı için bu eksiklik önemlidir. Bu tür akışları düzenli biçimde incelemek için birebir Python dersleri kapsamında fonksiyon sonuçlarını test etmeye dayalı çalışmalar yapılabilir.
Fonksiyonu, her akışta sayısal değer döndürecek şekilde düzeltelim:
def siparis_indirimi(tutar):
if tutar >= 1000:
return tutar * 0.90
else:
return tutar
sonuc = siparis_indirimi(500)
print("Ödenecek tutar:", sonuc)
Artık indirimsiz dalda da çağıran koda 500 aktarılır. Böylece None yerine ödeme hesabında kullanılabilecek sayısal bir sonuç elde edilir.
Düzeltilen fonksiyon nasıl test edilir?
Fonksiyonun artık her koşulda bir değer döndürdüğünü görmek için yalnızca bir kez çalıştırmak yeterli değildir. Sipariş indirimi örneğinde üç farklı durumu test etmek gerekir: indirim koşulunu sağlayan sipariş, koşulu sağlamayan sipariş ve sınır değere yakın sipariş.
Örnekteki kuralı açıkça tanımlayalım: 100 TL ve üzerindeki siparişlere %10 indirim uygulanacak, 100 TL’nin altındaki siparişlerde indirim yapılmayacak. Sonuç iki ondalık basamağa yuvarlanacaktır.
def indirimli_fiyat(siparis_tutari):
if siparis_tutari >= 100:
return round(siparis_tutari * 0.90, 2)
return round(siparis_tutari, 2)
Şimdi fonksiyonu farklı girdilerle çalıştırıp beklenen sonuçla gerçek sonucu karşılaştıralım:
| Giriş | Beklenen çıktı | Gerçek çıktı | Sonuç |
|---|---|---|---|
| 150 TL | 135 TL | 135 TL | Eşleşti |
| 80 TL | 80 TL | 80 TL | Eşleşti |
| 100,01 TL | 90,01 TL | 90,01 TL | Eşleşti |
İlk test, indirim uygulanması gereken normal bir siparişi kontrol eder. İkinci test, indirim sınırının altında kalan siparişte tutarın değiştirilmediğini gösterir. Üçüncü test ise 100 TL eşiğinin hemen üzerindeki değerde koşulun doğru çalışıp çalışmadığını denetler. İstersen temel kodlama kavramlarını ücretsiz bilgi testleriyle gözden geçirerek benzer koşul ve fonksiyon sorularını da çözebilirsin.
Bu kontrolleri her defasında elle yapmak yerine assert ifadeleriyle otomatikleştirebilirsin:
assert indirimli_fiyat(150) == 135
assert indirimli_fiyat(80) == 80
assert indirimli_fiyat(100.01) == 90.01
assert başarısız olursa Python, yazdığın varsayımın gerçekleşmediğini bildirir. Örneğin ilk satır başarısızsa indirim oranı, eşik değeri, matematiksel işlem veya fonksiyonun döndürdüğü değer sorgulanmalıdır. İkinci satır başarısızsa indirim uygulanmayan dalın yanlışlıkla değiştirilmiş olma ihtimali vardır. Sınır testi başarısız olduğunda ise >= yerine yanlışlıkla > kullanılıp kullanılmadığı kontrol edilmelidir.
None hatasını bulmak için kısa kontrol listesi
- Fonksiyon çağrısının sonucu değişkene atanıyor mu? Sipariş örneğinde
sonuc = indirimli_fiyat(150)gibi bir atama yoksa dönen değeri daha sonra kullanamazsın. - Tüm
returnifadeleri gerçekten çalışıyor mu? İndirim uygulanan dal çalışsa bile diğer daldareturnyoksa bazı siparişlerNonedöndürebilir. - Yalnızca
print()mi kullanılmış? Tutar ekranda görünüyor fakat değişkendeNonevarsa sonuç yazdırılmış, geri döndürülmemiştir. if,elifveelseakışının tamamı kapsanmış mı? 100 TL altı, 100 TL ve üzeri gibi bütün olasılıklar için fonksiyonun ne döndüreceği belirlenmelidir.- Dönen değer beklenen türde mi? Para hesabı beklenirken
None, metin veya beklenmeyen bir sayı dönüyorsa dönüş değerini kontrol et. - Çağıran kod değeri doğru biçimde mi kullanıyor? Fonksiyon doğru sonucu döndürse bile bu sonuç yanlış değişkenle kullanılabilir veya tekrar yalnızca ekrana yazdırılabilir.
Bu listeyi sırayla uyguladığında, sipariş fonksiyonundaki None değerinin eksik return mü, yanlış koşul mu yoksa print() ile return arasındaki karışıklık mı olduğunu daha hızlı ayırt edebilirsin.
Bir fonksiyonun None döndürmesi, öğrencinin yetersiz olduğunu göstermez. Fonksiyonun hangi girdide hangi dala girdiğini ve o dalda ne döndürdüğünü sistemli biçimde incelemek, hatayı görünür hâle getirir.
Sık Sorulan Sorular
Bir Python fonksiyonu return yazmadan biterse neden None döndürür?
Python’da bir fonksiyonun her çalışma yolunda açıkça değer döndürmesi gerekir. Fonksiyon return komutuna ulaşmadan sona ererse Python özel bir sonuç bulamaz ve varsayılan olarak None döndürür.
print() kullandığım hâlde fonksiyon sonucunu neden bir değişkende kullanamıyorum?
print() yalnızca değeri ekrana gösterir; değeri fonksiyonun çağrıldığı yere göndermez. Sonucu bir değişkende kullanmak istiyorsan ilgili değeri return ile döndürmelisin.
Koşullu ifadelerde hangi return dalının eksik olduğunu nasıl bulabilirim?
Fonksiyonun alabileceği farklı girdileri tek tek düşün ve her girdinin hangi if, elif veya else dalına girdiğini izle. Bir dalın sonunda return yoksa o koşulda None oluşabilir.
None dönen bir fonksiyon için assert nasıl yazılır?
Önce fonksiyonun belirli bir girdide hangi sonucu vermesi gerektiğini belirle, sonra bu beklentiyi assert ile yaz. Örneğin assert indirimli_fiyat(80) == 80 ifadesi, 80 TL’lik siparişte fonksiyonun 80 döndürmesi gerektiğini kontrol eder.
Beklenen ve gerçek sonuçları karşılaştırarak ilerlediğinde, None hatalarını tahminle değil, kanıta dayalı ve düzenli bir yöntemle çözebilirsin.