Bir fonksiyon, tek bir ilgili eylemi gerçekleştirmek için kullanılan, yeniden düzenlenebilir bir kod bloğudur. Fonksiyonlar, uygulamanız için daha iyi modülerlik yanı sıra kod yeniden kullanımı sağlar. Print gibi Python fonksiyonlarının yanı sıra kullanıcı tanımlı fonksiyonları oluşturup kullanabiliriz.
8.1. Bir fonksiyon tanımlama
Gerekli fonksiyonelliği sağlamak için fonksiyonları tanımlayabilirsiniz. Python’da bir fonksiyonu tanımlamak için basit kurallar:
- Fonksiyon blokları, sırasıyla anahtar kelime def, ardından fonksiyon adı ve parantez (()) içerir.
- Herhangi bir girdi parametresi veya argümanı bu parantez içine yerleştirilmelidir. Ayrıca bu parantez içindeki parametreleri de tanımlayabilirsiniz.
- Her fonksiyon içindeki kod bloğu bir kolonla başlar (:) ve girintili olarak oluşturulur.
- Bir işlevin ilk ifadesi isteğe bağlı bir yorum satırı (“…” içinde) olabilir. Özellikle fonksiyonu açıklamak için kullanılabilir.
- İfade [return] içeriyorsa, isteğe bağlı olarak fonksiyondan çıkılır. Hiçbir argüman içermeyen bir return veya Return None aynı anlama gelir ve değer döndürmez. Ayrıca, hiç return içermeyen bir fonksiyon tanımlanabilir.
Basitçe söz dizimi:
1 2 3 4 |
def fonksiyonismi( parametreler ): "fonksiyonu_analatan_satır" fonksiyon_ifadeleri return [ifade] |
Basit bir örnek,
1 2 3 4 |
def beniYaz( str ): "Bu satır yorum satırı gibi davranır. Yorumlanmadan geçer. Fonksiyon açıklaması için kullanılır." print(str) return |
beniYaz fonksiyonu dışarıdan bir değer alarak terminal ekranına çıktı üreten bir fonksiyondur. return değeri herhangi bir değer döndürmemektedir, sadece fonksiyon bu satırla birlikte sonlanır.
8.2. Fonksiyon çağırma
Bir fonksiyon tamamlandıktan sonra, başka bir fonksiyondan veya doğrudan Python komutundan ismi ve parametre bilgileri kullanılarak çağrılabilir. Örneğin, üste yazdığımız fonksiyonu çağırmak için,
1 2 |
beniYaz("Merhaba ben fonksiyon!") beniYaz("Merhaba ben fonksiyon 2!") |
1 2 |
Merhaba ben fonksiyon! Merhaba ben fonksiyon 2! |
8.3. Parametre aktarımı: Referans vs. Değer
Python dilinde tüm parametreler (argümanlar) referans olarak iletilir. Bir parametrenin bir fonksiyon içinde ne ifade ettiğini değiştirirseniz, değişiklik aynı zamanda çağırma işlemine geri yansır. Örneğin,
1 2 3 4 5 6 7 8 9 10 |
def beniDegistir( mylist ): "Bu değişiklik list'e yansır" mylist.append([1,2,3,4]); print("Fonksiyon içindeki değerler: ", mylist) return mylist = [10,20,30] print("Fonksiyon çağrılmadan önce list: ", mylist) beniDegistir( mylist ) print("Fonksiyon çağrılmasından sonra list: ", mylist) |
1 2 3 |
Fonksiyon çağrılmadan önce list: [10, 20, 30] Fonksiyon içindeki değerler: [10, 20, 30, [1, 2, 3, 4]] Fonksiyon çağrılmasından sonra list: [10, 20, 30, [1, 2, 3, 4]] |
Bir değişkenin referans türü iletildiğinde aslında bellek adresi iletilmiş olur. Modern programlama dillerinin çoğu bu özelliğe dolaylı yollardan destek verir. Örneğin C# ref deyimi ile referans türü atamaya destek verir. Ancak, fonksiyona dışarıdan gelen değere fonksiyon içinde atama işlemi yaptığımızda yeni bir değişkenmiş gibi davranır. Örneğin,
1 2 3 4 5 6 7 8 9 10 |
def benidegistir2( mylist ): "List'e yeni atama yapınca" mylist = [1,2,3,4]; # Yeni bir atama yapınca, yeni bir bellek bölgesi açılır. Başka bir deyişle yeni bir referansa sahiptir. print("Fonksiyon içindeki değer: ", mylist) return mylist = [10,20,30]; print("Fonksiyon çalışmadan önceki değer: ", mylist) benidegistir2( mylist ) print("Fonksiyon çalışması sonrası değer: ", mylist) |
1 2 3 |
Fonksiyon çalışmadan önceki değer: [10, 20, 30] Fonksiyon içindeki değer: [1, 2, 3, 4] Fonksiyon çalışması sonrası değer: [10, 20, 30] |
8.4. Fonksiyon Argümanları
Aşağıdaki argüman türlerini kullanarak bir fonksiyonu çağırabilirsiniz:
- Gerekli argümanlar
- Anahtar kelime argümanları
- Varsayılan argümanlar
- Değişken uzunlukta argümanlar
8.4.1. Gerekli argümanlar
Python’da bir fonksiyona argüman/lar (parametre/ler) sahip ise çağırmak için tüm argümanlara sırasıyla değer gönderilmelidir. Eğer argüman sayısı yetersiz olursa yorumlayıcı hata verir. Örneğin bir önceki bölümdeki fonksiyonu çağıralım,
1 |
benidegistir2() |
1 2 3 4 5 6 |
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-10-7e3911348b84> in <module>() ----> 1 benidegistir2() TypeError: benidegistir2() missing 1 required positional argument: 'mylist' |
Argüman girilmediği için hata mesajı verir. Çoğu programlama dili için bu durum geçerlidir. Kullandığım diller arasında sadece JavaScript argüman sayısı konusunda esnek bir yapıya sahiptir.
8.4.2. Anahtar argümanlar
Anahtar argümanları, fonksiyon parametrelerine değer gönderilmesi ile alakalıdır. Değer gönderirken hangi parametre değer gönderdiğinizi belirlersiniz. Bu sayede değerleri belli bir sıra olmadan fonksiyona gönderebilirsiniz. Örneğin,
1 2 3 4 5 6 7 |
def infoYaz( ad, yas ): "İki parametreli fonksiyon" print("Adı: ", ad) print("Yaşı ", yas) return infoYaz( yas=50, ad="miki" ) |
1 2 |
Adı: miki Yaşı 50 |
Anahtar değer kullanmadan değer gönderebiliriz. Ancak bu durumda parametre sıralamasının önemli olduğu unutmayalım. Anahtar yapısı sayesinde daha esnek bir yapıya kavuşabiliriz. Anahtar kullanmadan,
1 |
infoYaz("miki", 50) |
1 2 |
Adı: miki Yaşı 50 |
8.4.3. Varsayılan argümanlar
Varsayılan argüman, bir fonksiyonun içindeki argümanlara varsayılan bir değer atamasıdır. Bir argümana varsayılan bir değer atanırsa fonksiyon çağrılırken bu değer boş geçilebilir. Başka bir deyişle argümana değer gönderilmese de varsayılan değer olduğu için kod çalışır. Örneğin,
1 2 3 4 5 6 7 8 9 10 |
def infoYaz2( ad, yas = 35 ): "İki parametreli fonksiyon-varsayılan değer örneği" print("Adı: ", ad) print("Yaşı ", yas) return infoYaz2( "miki", 45 ) infoYaz2( yas=50, ad="miki" ) infoYaz2(ad="miki") infoYaz2("miki") |
1 2 3 4 5 6 7 8 |
Adı: miki Yaşı 45 Adı: miki Yaşı 50 Adı: miki Yaşı 35 Adı: miki Yaşı 35 |
Varsayılan değer ataması sayesinde fonksiyona eksik değer göndersekte sorun olmaz.
8.4.4. Değişken uzunlukta argümanlar
Fonksiyon tanımlarken argüman sayısı belirsiz olabilir. Bu tür argüman sayısı belli olmayan fonksiyonlar değişken uzunluklu argümanlar olarak adlandırılır. Bu tür bir yapı kurmak için aşağıdaki sözdizimi kullanılır:
1 2 3 4 |
def fonksiyonismi([formal_args,] *var_args_tuple ): "fonksyion açıklaması" fonksiyon kodlari return [ifade] |
Yıldız karakterini (*) görünce C dilini hatırlayan öğrencilerin aklına pointer konusu gelmiştir. Bu yapı sistemimize esneklik kazandırır. İster * karakteri ile başlayan değişkene değer gönderin, isterseniz göndermeyin. Program çalışır. Örneğin standart bir argüman ve * ile başlayan bir argüman tanımlayalım.
1 2 3 4 5 6 7 8 9 |
def infoYaz3( arg1, *vartuple ): "Değişken uzunlukta argüman" print("arg1: ", arg1) for var in vartuple: print("*->", var) return infoYaz3( 10 ) infoYaz3( 70, 60, 50 ) |
1 2 3 4 |
arg1: 10 arg1: 70 *-> 60 *-> 50 |
arg1 değişkeni değer göndermek zorunda olduğumuzu unutmayın. Ama * ile başlayan değişkenin esnek olduğunu görüyoruz.
8.5. Anonim (İsimsiz) Fonksiyonlar
Bu tür fonksiyonlar def anahtar sözcüğü kullanılmadan oluşturulabilir. Bir isimsiz fonksiyonları oluşturmak için lambda anahtar sözcüğü kullanılır. Bu fonksiyonların temel özellikleri
- Lambda ile üretilen fonksiyonlar herhangi bir sayıda argüman alabilir, ancak bir ifade şeklinde sadece bir değer döndürür.
- Lambda fonksiyonları isimsiz oldukları için direkt çağrılamaz çünkü lambda bir ifade gerektirir.
- Lambda fonksiyonları kendi yerel ad alanlarına sahiptir parametreleri ve sahip olduğu değişken dışında değişkenlere erişemez.
Sözdizimi:
1 |
lambda [arg1 [,arg2,.....argn]]:ifade |
Basit bir örnekle açıklayalım,
1 2 3 4 5 6 |
# lambda bir fonksiyon topla = lambda arg1, arg2: arg1 + arg2 # İsimsiz fonksiyon değişken üzerinden çağrılır. print("Değerlerin toplamı : ", topla( 10, 20 )) print("Değerlerin toplamı : ", topla( 20, 20 )) |
Değerlerin toplamı:
1 2 |
Değerlerin toplamı : 30 Değerlerin toplamı : 40 |
Dikkat edilirse, lambda fonsiyonu direkt çağrılamadı. Lambda fonksiyonu 2 argüman sahip ve bir değer döndürüyor. Bu isimsiz fonksiyonun kullanılabilmesi için bir değişkene atanıyor ve bu değişken üzerinden kullanılabiliyor.
8.5. Return ifadesi
return ifadesi fonksiyondan çıkılmasını sağlar. Eğer return ifadesinde hiçbir değer döndürülmüyorsa return None anlamına gelir. Bir anlamda C, C# veya Java’daki void fonksiyonları temsil etmiş olur. Önceki örneklerde hiç bir değer döndürülmemişti, şimdi bir fonksiyondan bir değer döndürelim.
1 2 3 4 5 6 |
def topla_fonk( arg1, arg2 ): toplam = arg1 + arg2 return toplam toplam = topla_fonk( 10, 20 ); print("Toplam sonucu : ", toplam) |
1 |
Toplam sonucu : 30 |
8.6. Değişkenlerin kapsamı
Bir programdaki tüm değişkenlere programın tüm konumlarına erişemeyebilir. Bu tür değişkenler kullandığımız yere bağımlıdır. Python’da iki temel değişken kapsamı vardır.
- Global (Genel)
- Local (Yerel)
Bir fonksiyonun altında tanımlanan değişkenlerin yerel kapsamı vardır. Dışarda tanımlanan değişkenlerin ise genel kapsamı vardır. Yerel değişkenlere sadece o fonksiyon içinden ulaşılırken, genel değişkenlere program içinde herhangi bir konumdan ulaşabilirsiniz. Eğer aynı isimde global ve local değişken tanımlanırsa öncelik local değişkenindir. Örneğin,
1 2 3 4 5 6 7 8 9 10 11 |
toplam = 0; # toplama fonksiyonu def toplama( arg1, arg2 ): # Toplama fonksiyonu toplam = arg1 + arg2 # Local değişken print("Fonksiyonun içi toplam: ", toplam) return toplam # Fonksiyonu çağırma toplama( 10, 20 ) print("Fonksiyonun dışındaki toplam: ", toplam) |
1 2 |
Fonksiyonun içi toplam: 30 Fonksiyonun dışındaki toplam: 0 |
Aşağıda toplam değişkeni global yapılmıştır.
1 2 3 4 5 6 7 8 9 10 11 12 |
toplam = 0; # toplama fonksiyonu def toplama( arg1, arg2 ): # Toplama fonksiyonu global toplam # Global değişken yapıldı toplam = arg1 + arg2 # Local değişken print("Fonksiyonun içi toplam: ", toplam) return toplam # Fonksiyonu çağırma toplama( 10, 20 ) print("Fonksiyonun dışındaki toplam: ", toplam) |
1 2 |
Fonksiyonun içi toplam: 30 Fonksiyonun dışındaki toplam: 30 |