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:
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.