Fonksiyonlar
Bölüm 4: Fonksiyonlar - Kodunuzu Organize Edin
4.1 Fonksiyonlar: Kod Tekrarından Kurtulun
Fonksiyonlar, belirli bir görevi yerine getiren, yeniden kullanılabilir kod bloklarıdır. Aynı işlemi tekrar tekrar yazmak yerine, bu işlemi bir fonksiyon içinde tanımlayabilir ve gerektiğinde çağırabiliriz. Bu, kod tekrarını azaltır, kodun okunabilirliğini artırır ve programların bakımını kolaylaştırır. Fonksiyonlar, bir programın yapı taşlarıdır ve büyük ve karmaşık bir programı daha küçük ve yönetilebilir parçalara (fonksiyonlara) ayırarak programı daha kolay anlamak, geliştirmek ve hata ayıklamak mümkün olur.
Fonksiyon Kullanmanın Faydaları:
- Kod Tekrarını Azaltır: Aynı işlemi tekrar tekrar yazmak yerine, bir kez fonksiyon olarak tanımlayabilir ve gerektiğinde çağırabiliriz.
- Kod Okunabilirliğini Artırır: Fonksiyonlar, kodun daha düzenli ve anlaşılır olmasını sağlar.
- Kod Bakımını Kolaylaştırır: Fonksiyonlar, kodun daha kolay değiştirilmesini ve güncellenmesini sağlar.
4.2 Fonksiyon Tanımlama
Python’da bir fonksiyon tanımlamak için def
anahtar kelimesini kullanırız. Fonksiyon tanımının sözdizimi şu şekildedir:
def fonksiyon_adi(parametre1, parametre2, ...):
"""Fonksiyonun açıklaması (docstring)"""
# Fonksiyonun gövdesi
# Yapılacak işlemler
return deger # İsteğe bağlı
def
: Fonksiyon tanımı olduğunu belirten anahtar kelime.fonksiyon_adi
: Fonksiyonun adı. Fonksiyon adları, değişken isimleriyle aynı kurallara tabidir.parametre1, parametre2, ...
: Fonksiyona verilecek girdiler (isteğe bağlı)."""Fonksiyonun açıklaması (docstring)"""
: Fonksiyonun ne yaptığını açıklayan bir metin (isteğe bağlı).Fonksiyonun gövdesi
: Fonksiyonun yapacağı işlemleri içeren kod bloğu.return deger
: Fonksiyonun döndüreceği değer (isteğe bağlı).
Örnekler:
def selamla():
"""Ekrana bir selamlama mesajı yazdırır."""
print("Merhaba!")
def selamla(isim):
"""Verilen isimle bir selamlama mesajı yazdırır."""
print(f"Merhaba {isim}!")
def topla(sayi1, sayi2):
"""İki sayıyı toplar ve sonucu döndürür."""
= sayi1 + sayi2
toplam return toplam
def find_largest_number(number1, number2, number3):
"""Üç sayıdan en büyüğünü döndürür."""
if number1 >= number2 and number1 >= number3:
return number1
elif number2 >= number1 and number2 >= number3:
return number2
else:
return number3
4.3 Fonksiyon Çağırma
Bir fonksiyonu çağırmak için, fonksiyonun adını ve ardından parantez içinde argümanları (eğer varsa) yazarız. Argümanlar, fonksiyona verilen girdilerdir.
Örnekler:
# selamla() fonksiyonunu çağırır
selamla()
"Ahmet") # selamla() fonksiyonunu "Ahmet" argümanıyla çağırır
selamla(
= topla(5, 3) # topla() fonksiyonunu 5 ve 3 argümanlarıyla çağırır ve sonucu sonuc değişkenine atar
sonuc print(sonuc) # Çıktı: 8
4.4 Geri Dönüş Değerleri (Return Values)
Fonksiyonlar, işlemlerini tamamladıktan sonra bir değer döndürebilir. Bu değer, return
ifadesi ile belirtilir. Eğer return
ifadesi kullanılmazsa, fonksiyon None
değerini döndürür.
Örnek:
def mutlak_deger(sayi):
"""Verilen sayının mutlak değerini döndürür."""
if sayi < 0:
return -sayi
else:
return sayi
= mutlak_deger(-10)
sonuc print(sonuc) # Çıktı: 10
4.5 Fonksiyonların Kapsamı (Scope)
Bir değişkenin kapsamı (scope), o değişkenin programın hangi bölümlerinde erişilebilir olduğunu belirler. Fonksiyonlar, kendi yerel kapsamlarına (local scope) sahiptir. Bu, fonksiyon içinde tanımlanan değişkenlerin, fonksiyon dışında erişilemeyeceği anlamına gelir.
Örnek:
= 10 # Global değişken x
x
def function():
= 5 # Local değişken x
x print("Fonksiyon içinde x: ", x)
# Fonksiyon çağrısı
function() print("Fonksiyon dışında x: ", x)
Çıktı:
Fonksiyon içinde x: 5
Fonksiyon dışında x: 10
Global Değişkenleri Değiştirme
Bir fonksiyon içinde global bir değişkeni değiştirmek için, global
anahtar kelimesini kullanmamız gerekir.
global
anahtar kelimesini dikkatli kullanın! Fonksiyonlar içinde global değişkenleri değiştirmek, kodun okunabilirliğini ve bakımını zorlaştırabilir ve beklenmedik sonuçlara yol açabilir. Mümkün olduğunca, fonksiyonların yan etkilerinden kaçınmak ve değerleri return
ifadesi ile döndürmek daha iyi bir uygulamadır.
Örnek:
= 10 # global x
x
def fonksiyon():
global x
= 20 # global x'i güncelle
x
print(x)
fonksiyon()print(x)
Çıktı:
10
20
İç İçe Fonksiyonlar ve Kapsamlar
Bir fonksiyonun içinde başka bir fonksiyon tanımlayabiliriz. İçteki fonksiyon, dıştaki fonksiyonun yerel kapsamına ve global kapsama erişebilir. İçteki fonksiyon, dıştaki fonksiyonun yerel değişkenini değiştirmek için nonlocal
anahtar kelimesini kullanabilir.
Örnek:
def dis_fonksiyon():
= 10
a print(f"Dış fonksiyon içinde a: {a}")
def ic_fonksiyon():
nonlocal a
= 20
a print(f"İç fonksiyon içinde a: {a}")
ic_fonksiyon()print(f"Dış fonksiyon içinde a: {a}")
dis_fonksiyon()
Çıktı:
Dış fonksiyon içinde a: 10
İç fonksiyon içinde a: 20
Dış fonksiyon içinde a: 20
4.6 Varsayılan Parametre Değerleri
Fonksiyon tanımlarında parametrelere varsayılan değerler atayabiliriz. Bu sayede, fonksiyon çağrılırken bu parametreler için bir argüman verilmezse, varsayılan değer kullanılır.
Örnekler:
def selamla(isim="Kullanıcı"):
"""Verilen isimle bir selamlama mesajı yazdırır.
İsim verilmezse, "Kullanıcı" ismi kullanılır.
"""
print(f"Merhaba {isim}!")
# Çıktı: Merhaba Kullanıcı!
selamla() "Ahmet") # Çıktı: Merhaba Ahmet!
selamla(
def us_al(sayi, us=2):
"""Verilen sayıyı verilen üsse yükseltir.
Üs belirtilmezse, varsayılan olarak 2 kullanılır.
"""
return sayi ** us
print(us_al(3)) # Çıktı: 9 (3^2)
print(us_al(3, 3)) # Çıktı: 27 (3^3)
4.7 Değişken Sayıda Argüman (*args
ve **kwargs
)
Fonksiyonlar, değişken sayıda argüman alabilir. *args
ile değişken sayıda konumsal argüman, **kwargs
ile de değişken sayıda anahtar kelime argümanı alabiliriz.
Örnek:
def topla(*args):
"""Değişken sayıda sayıyı toplar."""
= 0
toplam for sayi in args:
+= sayi
toplam return toplam
print(topla(1, 2)) # Çıktı: 3
print(topla(10, 20, 30, 40)) # Çıktı: 100
Örnek:
def ogrenci_bilgileri(**kwargs):
"""Öğrenci bilgilerini yazdırır."""
for anahtar, deger in kwargs.items():
print(f"{anahtar}: {deger}")
="Ahmet", soyisim="Yılmaz", numara=12345) ogrenci_bilgileri(isim
Çıktı:
isim: Ahmet
soyisim: Yılmaz
numara: 12345
Önemli:
Fonksiyon tanımlarında *args
ve **kwargs
sıralaması önemlidir. Önce *args
, sonra **kwargs
gelmelidir.
def my_func(*args, **kwargs):
print("Args:", args)
print("Kwargs:", kwargs)
Doğru Kullanım:
1, "another_value", some_key="value") my_func(
Çıktı:
Args: (1, 'another_value')
Kwargs: {'some_key': 'value'}
1, some_key="value", "another_value") # Bu hata verir. my_func(
4.8 Lambda Fonksiyonları
Lambda fonksiyonları, Python’da kısa ve basit fonksiyonları tek satırda tanımlamak için kullanılır. Özellikle, fonksiyonun karmaşık bir yapısı yoksa ve sadece bir ifadeyi hesaplayıp döndürüyorsa, lambda fonksiyonları kullanışlı olabilir. lambda fonksiyonlarının bir adı yoktur ve genellikle bir değişkene atanır.
Sözdizimi:
lambda argümanlar: ifade
Örnekler:
= lambda x: x*x
kare_al print(kare_al(5)) # Çıktı: 25
= lambda x: x%2 == 0
cift_mi = lambda x, y: x + y
topla
print(cift_mi(6)) # Çıktı: True
print(cift_mi(5)) # Çıktı: False
print(topla(3, 5)) # Çıktı: 8
Lambda Fonksiyonları Ne Zaman Kullanılmamalı?
Karmaşık İşlemler: Eğer fonksiyonunuzda birden fazla ifade veya döngü varsa, lambda fonksiyonu kullanmak kodun okunabilirliğini azaltabilir. Bu durumlarda normal fonksiyon tanımını kullanmak daha iyidir.
Yan Etkiler: Lambda fonksiyonları, genellikle sadece bir ifadeyi hesaplayıp döndürdükleri için yan etkiler (global değişkenleri değiştirmek, dosya işlemleri yapmak gibi) yaratmak için uygun değildir. Eğer fonksiyonunuzun yan etkileri olması gerekiyorsa, normal def
ile fonksiyon tanımını kullanmalısınız.
4.9 pass
İfadesi
pass
ifadesi, Python’da hiçbir şey yapmayan bir ifadedir. Genellikle kod bloklarını henüz tamamlanmadığı veya geçici olarak boş bırakılması gereken durumlarda kullanılır.
Örnek:
def fonksiyon():
pass # Bu fonksiyon daha sonra tamamlanacak.
4.10 Özyineli Fonksiyonlar (Recursive Functions)
Özyineli fonksiyonlar, kendini çağıran fonksiyonlardır. Özyineli fonksiyonlar, bazı problemleri çözmek için oldukça zarif ve etkili bir yöntemdir. Özyineli fonksiyonlar, problemi daha küçük alt problemlere bölerek çözer ve her alt problemi aynı fonksiyonu kullanarak tekrar tekrar çözer.
Özyineli fonksiyon yazarken dikkatli olun! Eğer temel durumu doğru bir şekilde tanımlamazsanız, fonksiyon sonsuz döngüye girebilir ve programınız çökebilir.
Özyinelemenin Temel Mantığı
Temel Durum (Base Case): Her özyineli fonksiyonun, özyinelemenin durduğu bir temel durumu olmalıdır. Temel durum, problemin en küçük ve çözümü bilinen halidir.
Özyineli Adım (Recursive Step): Temel duruma ulaşılmadığı sürece, fonksiyon kendini daha küçük bir girdiyle tekrar çağırır. Her çağrıda, problem daha da basitleştirilir.
Örnek Problem: Faktöriyel Hesaplama
def faktoriyel(n):
"""Verilen sayının faktöriyelini hesaplar."""
if n == 0:
return 1
else:
return n * faktoriyel(n-1)
print(faktoriyel(5)) # Çıktı: 120
Adım Adım Özyineleme
faktoriyel(5)
çağrısı nasıl çalışır?
faktoriyel(5)
çağrılır. 5, 0’a eşit olmadığı içinelse
bloğuna girilir.faktoriyel(5) = 5 * faktoriyel(4)
olarak hesaplanır.faktoriyel(4) = 4 * faktoriyel(3)
olarak hesaplanır.- Bu işlem
faktoriyel(1)
vefaktoriyel(0)
’a kadar devam eder. faktoriyel(0)
’ın değeri 1’dir.- Döndürülen değerler zinciri geriye doğru işlenir:
faktoriyel(1) = 1
faktoriyel(2) = 2 * faktoriyel(1) = 2 * 1 = 2
faktoriyel(3) = 3 * faktoriyel(2) = 3 * 2 = 6
faktoriyel(4) = 4 * faktoriyel(3) = 4 * 6 = 24
faktoriyel(5) = 5 * faktoriyel(4) = 5 * 24 = 120
- Sonuç: 120
Örnek Problem: Fibonacci Dizisi
1, 1, 2, 3, 5, 8, 13, 21, 34, ...
def fibonacci(n):
"""Fibonacci dizisinin n'inci elemanını döndürür."""
if n <= 1:
return n
else:
return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(6)) # Çıktı: 8
print(fibonacci(10)) # Çıktı: 55
Adım Adım Özyineleme
fibonacci(6)
çağrısı nasıl çalışır?
fibonacci(6)
çağrılır. 6, 1’den küçük olmadığı içinelse
bloğuna girilir.fibonacci(6) = fibonacci(5) + fibonacci(4)
olarak hesaplanır.fibonacci(5) = fibonacci(4) + fibonacci(3)
olarak hesaplanır.- Bu işlem
fibonacci(1)
vefibonacci(2)
’ye kadar devam eder. fibonacci(1)
vefibonacci(2)
’nin değerleri sırasıyla 1 ve 1’dir.- Döndürülen değerler zinciri geriye doğru işlenir:
fibonacci(2) = fibonacci(1) + fibonacci(0) = 1 + 0 = 1
fibonacci(3) = fibonacci(2) + fibonacci(1) = 1 + 1 = 2
fibonacci(4) = fibonacci(3) + fibonacci(2) = 2 + 1 = 3
fibonacci(5) = fibonacci(4) + fibonacci(3) = 3 + 2 = 5
fibonacci(6) = fibonacci(5) + fibonacci(4) = 5 + 3 = 8
4.11 Alıştırmalar
- Kullanıcıdan iki sayı alan ve bu sayıların toplamını, farkını, çarpımını ve bölümünü hesaplayan 4 ayrı fonksiyon yazın.
- Kullanıcıdan bir metin alan ve bu metnin içindeki sesli harflerin sayısını döndüren bir fonksiyon yazın.
- Kullanıcıdan bir liste alan ve bu listedeki en büyük sayıyı bulan bir fonksiyon yazın.
- Girilen bir sayının asal olup olmadığını kontrol eden bir fonksiyon yazın.
- Kullanıcıdan bir cümle alın ve bu cümledeki kelimeleri bir liste olarak döndüren bir fonksiyon yazın.
- Bir listenin elemanlarını toplayan bir fonksiyon yazın, ancak liste boş ise 0 döndürsün.
- Bir metni tersine çeviren bir fonksiyon yazın. Örneğin, “Merhaba” metni “abaleM” olarak döndürülsün.
- Bir metindeki her kelimenin ilk harfini büyük harfe dönüştüren bir fonksiyon yazın. Örneğin, “python programlama dili” metni “Python Programlama Dili” olarak döndürülsün.
- Girilen bir sayının 2’nin kuvveti olup olmadığını kontrol eden bir fonksiyon yazın.