İşlev Tanımlama
Önceki Akış Denetimi Sonraki
İşlev Tanımlama
Herhangi bir değere kadar Fibonacci serisi yazan bir işlev yazalım:
>>> def fib(n):     # n'e kadar Fibonacci serisini yazdır
...     "n'e kadar Fibonacci serisini yazdır"
...     a, b = 0, 1
...     while b < n:
...         print b,
...         a, b = b, a+b
...
>>> # Tanımladığımız işlevi çağıralım:
... fib(2000)
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597
def anahtar kelimesi bir işlev tanımını başlatır. Bu deyimden sonra bir işlev adı ve parantez içinde parametreler yazılır. İşlevin gövdesini oluşturan program satırları sonraki satırdan itibaren girintili olarak yazılırlar. İşlev gövdesinin ilk satırı bir dizge de olabilir; bu dizge işlevin belgelenmesinde kullanılır (docstring).
İşlevlerin belgelenmesinde kullanılan dizgeleri (docstring) otomatik olarak çevrim içi ya da basılı belgeler oluşturmak için kullanan yazılımlar vardır. Ayrıca bazı geliştirme ortamları bunları program yazarken kolaylık sağlaması için etkileşimli olarak programcıya sunarlar. Yazdığınız işlevlere bunları eklemeyi bir alışkanlık haline getirmeniz faydalı olur.
Bir işlevin çağrılması (çalıştırılması) bu işlevdeki yerel değişkenlerin olduğu bir simge tablosu oluşturur. İşlev içerisinde bütün değer atama işlemlerinde değerler yerel simge tablosuna kaydedilir. Bir değişkene başvuru durumunda ise önce yerel (local), sonra genel (global) ve en son yerleşik (built-in) simge tablosunda arama yapılır. Bu yüzden genel değişkenlere doğrudan değer atama yapılamaz (eğer global ifadesi içinde kullanılmamışlar ise); ancak bunlara başvuru yapılabilir (reference).
İşlev çağırıldığında işlevin parametreleri yerel simge tablosuna eklenirler; yani parametreler işleve değeri ile çağrı (call by value) kullanılarak iletilirler (yani parametreye yapılan değişiklikler yereldir, çağıran işlevdeki argümanlarda bir değişme olmaz). [85]
Bir işlev başka bir işlevi çağırdığında bu çağrı için yeni bir yerel simge tablosu oluşturulur.
Bir işlev tanımı işlev adının yürürlükte olan simge tablosuna eklenmesine sebep olur. İşlevin adı yorurumlayıcı tarafından kullanıcı tanımlı işlev veri türü olarak tanınır. Bu değer başka bir isime atanabilir ve bu da bir işlev olarak kullanılabilir. Bu genel bir isim değiştirme yolu olabilir:
>>> fib
<function object at 10042ed0>
>>> f = fib # f de fib işlevi olur
>>> f(100)
1 1 2 3 5 8 13 21 34 55 89
fib'in bir işlev olmayıp bir yordam (procedure) olduğunu düşünebilirsiniz. Python'da yordamlar, çağıran işleve değer geri döndürmeyen işlevlerdir. Aslında yordamlar da bir değer geri döndürürler, ama bu sıkıcı bir konudur. Bu değere None denir ve yerleşik bir değişkendir. Yorumlayıcı yazılacak tek değer bu ise normalde None yazmaz. Bunu görmeyi çok istiyorsanız şunu deneyin:
>>> print fib(0)
None
Fibonacci serisini yazdırmak yerine, bunu bir liste şeklinde geri döndüren işlev yazmak basittir:
>>> def fib2(n): # n e kadar fibonacci serisi geri döndürür
...     " n e kadar fibonacci serisi içeren liste geri döndürür"
...     sonuc = []
...     a, b = 0, 1
...     while b < n:
...         sonuc.append(b)    # değeri listeye ekle
...         a, b = b, a+b
...     return sonuc
...
>>> f100 = fib2(100)    # işlevi çağır
>>> f100                # sonucu yazdır
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
Bu örnekte de bazı yeni Python özelliklerini görüyoruz:
  • return deyimi bir işlevden değer geri döndürür. Parametresi olmayan bir return deyimi None geri döndürür. Sona eren bir yordam (procedure) da None geri döndürür.
  • sonuc.append(b) ifadesi sonuç liste nesnesinin bir yöntemini çağırmaktadır. Bir yöntem bir nesneye `ait olan' ve nesne.yöntemAdı şeklinde adlandırılan bir işlevdir. nesne.yöntemAdı ifadesinde nesne herhangi bir nesne (bir ifade de olabilir) ve yöntemAdı da nesnenin türüne bağlı bir yöntemdir. Farklı veri türleri farklı yöntemlere sahiptirler. Farklı veri türlerinin ayni isimli yöntemleri olabilir. Sonraki bölümlerde anlatılacağı gibi, kendi veri türlerinizi ve yöntemlerinizi oluşturmanız mümkündür. Yukarıdaki örnekte görülen append() yöntemi liste nesneleri için tanımlıdır ve bir listenin sonuna yeni elemanlar ekler. Bu örnekte bu sonuc = sonuc + [b] ifadesinin yaptığını yapar; ancak daha verimlidir.


[85] Aslında nesne başvurusu ile çağrı daha iyi bir tanım olur, çünkü işleve değiştirilebilir bir nesne aktarılırsa çağıran çağrılanın o nesneye uyguladığı tüm değişiklikleri görür (listeye eklenen elemanlar gibi).
Önceki Üst Ana Başlık Sonraki
pass Deyimi Başlangıç İşlev Tanımları Üzerine Daha Fazla Bilgi
Bir Linux Kitaplığı Sayfası