Kurs

Fonksiyonlar, Python programlama dilinin vazgeçilmez bir parçasıdır: Python diline yerleşik gelen ya da kütüphane ekosistemiyle sunulan pek çok harika fonksiyonla muhtemelen şimdiden karşılaştınız ve bazılarını kullandınız. Ancak bir veri bilimci olarak, verinizin size sunduğu problemleri çözmek için sürekli kendi fonksiyonlarınızı yazmanız gerekecek.
Bu eğitimdeki tüm örnek kodları kendiniz kolayca çalıştırmak için, Python’ın önceden kurulu olduğu ve tüm kod örneklerini içeren ücretsiz bir DataLab çalışma kitabı oluşturabilirsiniz. Python fonksiyonları yazma pratiği için bu uygulamalı DataCamp alıştırmasına da göz atın veya Python Data Science Toolbox kursumuzu deneyin!
Python’da Fonksiyonlar
Programlamada fonksiyonları, tekrar tekrar kullanmak istediğiniz ya da karmaşıklıkları nedeniyle ayrı bir alt programda tanımlanıp gerektiğinde çağrılması daha iyi olan talimatları bir araya getirmek için kullanırsınız. Yani bir fonksiyon, belirli bir görevi yerine getirmek için yazılmış bir kod parçasıdır. Bu belirli görevi yerine getirmek için fonksiyonun birden fazla girdiye ihtiyacı olabilir de olmayabilir de. Görev tamamlandığında fonksiyon bir veya daha fazla değer döndürebilir ya da döndürmeyebilir.
Python’da üç tür fonksiyon vardır:
-
help()ile yardım istemek,min()ile minimum değeri almak,print()ile bir nesneyi terminale yazdırmak gibi yerleşik (built-in) fonksiyonlar… Bu fonksiyonlardan daha fazlasının bir özetini burada bulabilirsiniz. -
Kullanıcı tanımlı fonksiyonlar (User-Defined Functions, UDF), yani kullanıcıların kendilerine yardımcı olması için oluşturdukları fonksiyonlar; ve
-
Anonim fonksiyonlar; standart
defanahtar sözcüğüyle bildirilmedikleri için lambda fonksiyonları olarak da adlandırılır.
Fonksiyonlar ve metotlar
Metot, bir sınıfın parçası olan fonksiyona denir. Ona sınıfın bir örneği/nesnesi üzerinden erişirsiniz. Fonksiyonlarda bu kısıt yoktur: bağımsız bir fonksiyona atıfta bulunur. Bu şu anlama gelir: Tüm metotlar fonksiyondur, ancak tüm fonksiyonlar metot değildir.
Önce bir plus() fonksiyonu tanımladığınız, ardından sum() metoduna sahip bir Summation sınıfı oluşturduğunuz şu örneği düşünün:
Artık Summation sınıfının bir parçası olan sum() metodunu çağırmak isterseniz, önce o sınıfın bir örneğini/nesnesini tanımlamanız gerekir. O hâlde böyle bir nesne tanımlayalım:
plus() fonksiyonunu çağırmak istediğinizde bu örneklemeyi yapmanız gerekmediğini unutmayın! DataCamp Light kod bloğunda plus(1,2) komutunu sorunsuzca çalıştırabilirsiniz!
Parametreler ve argümanlar
Parametreler, bir fonksiyon ya da metodu tanımlarken kullanılan ve argümanların eşleneceği isimlerdir. Başka bir deyişle, argümanlar herhangi bir fonksiyon ya da metot çağrısına sağlanan değerlerdir; fonksiyon ya da metot kodu argümanlara parametre adlarıyla atıfta bulunur.
Aşağıdaki örneği ve yukarıdaki DataCamp Light bloğunu düşünün: Summation sınıfının sum() metoduna iki argüman geçirirsiniz; oysa daha önce üç parametre tanımlamıştınız: self, a ve b.
Peki self’e ne oldu?
Her sınıf metodunun ilk argümanı daima sınıfın mevcut örneğine bir referanstır; bu örnekte bu sınıf Summation’dır. Gelenek gereği bu argüman self olarak adlandırılır.
Bu, bu durumda self referansını iletmediğiniz anlamına gelir; çünkü self, bir metodun hangi örnek üzerinden çağrıldığını belirten ve örtük olarak geçirilen argümanın parametre adıdır. Argüman listesine kendiliğinden eklenir.
Bir Fonksiyon Nasıl Tanımlanır: Kullanıcı Tanımlı Fonksiyonlar (UDF)
Python’da bir fonksiyonu tanımlamanın dört adımı şunlardır:
-
Fonksiyonu bildirmek için
defanahtar sözcüğünü kullanın ve ardından fonksiyon adını yazın. -
Fonksiyona parametreler ekleyin: bunlar fonksiyonun parantezleri içinde yer almalıdır. Satırı iki nokta üst üste ile bitirin.
-
Fonksiyonun yürütmesi gereken ifadeleri ekleyin.
-
Fonksiyonun bir çıktı üretmesi gerekiyorsa bir return ifadesiyle bitirin. Return ifadesi olmadan fonksiyonunuz
Nonenesnesini döndürür.
Elbette, ilerledikçe fonksiyonlarınız daha karmaşık hâle gelecektir: for döngüleri, akış kontrolü, … ve daha fazlasını ekleyerek daha ince ayar yapabilirsiniz:
def hello():
name = str(input("Enter your name: "))
if name:
print ("Hello " + str(name))
else:
print("Hello World")
return
hello()
Yukarıdaki fonksiyonda kullanıcıdan bir isim girmesi istenir. İsim girilmezse fonksiyon “Hello World” yazdırır. Aksi hâlde kullanıcıya kişiselleştirilmiş bir “Hello” yanıtı verilir.
Unutmayın ki UDF’iniz için bir ya da daha fazla fonksiyon parametresi tanımlayabilirsiniz. Bunu Fonksiyon Argümanları bölümünde daha ayrıntılı öğreneceksiniz. Ayrıca fonksiyonunuzun sonucu olarak bir veya birden çok değer döndürebilirsiniz ya da döndürmeyebilirsiniz.
Return ifadesi
UDF’inizde hello() içinde bir şey yazdırdığınız için bunu gerçekten döndürmeniz gerekmediğini unutmayın. Yukarıdaki fonksiyonla bunun arasında herhangi bir fark olmayacaktır:
Ancak fonksiyonunuzun sonucuyla çalışmaya devam etmek ve üzerinde bazı işlemler denemek istiyorsanız, bir değer (örneğin bir String, bir tamsayı, …) gerçekten döndürmek için return ifadesini kullanmanız gerekir. Aşağıdaki senaryoya bakın: hello() bir "hello" String’i döndürürken, hello_noreturn() fonksiyonu None döndürür:
İkinci fonksiyon size bir hata verir; çünkü None ile herhangi bir işlem yapamazsınız. NoneType (hello_noreturn()’ın sonucu olan None) ile int (2) için çarpma işlemi yapılamayacağını söyleyen bir TypeError alırsınız.
İpucu fonksiyonlar bir return ifadesine rastladıklarında, herhangi bir değer döndürmeyecek olsalar bile, derhal çıkarlar:
return ifadesiyle çalışırken bahsetmeye değer bir diğer nokta da birden çok değer döndürmek için bunu kullanabileceğinizdir. Bunu yapmak için demetlerden (tuple) yararlanırsınız.
Unutmayın bu veri yapısı, listeye çok benzer: Birden fazla değer içerebilir. Ancak demetler değiştirilemezdir (immutable); yani içinde saklanan değerleri değiştiremezsiniz! Çift parantez () yardımıyla oluşturursunuz. Virgül ve atama operatörü yardımıyla demetleri birden fazla değişkene açabilirsiniz (unpack).
Fonksiyonunuzun nasıl birden fazla değer döndürebileceğini anlamak için aşağıdaki örneğe göz atın:
Not return ifadesindeki return sum, a yazımı, return (sum, a) ile aynı sonucu verir: İlki aslında perde arkasında sum ve a değerlerini bir demete paketler!
Bir fonksiyon nasıl çağrılır
Önceki bölümlerde bir fonksiyonun nasıl çağrılacağına dair pek çok örnek gördünüz. Bir fonksiyonu çağırmak, tanımladığınız fonksiyonu çalıştırmak demektir — bunu doğrudan Python isteminden ya da başka bir fonksiyon aracılığıyla ("İç İçe Fonksiyonlar" bölümünde göreceğiniz gibi) yapabilirsiniz.
Yeni tanımladığınız hello() fonksiyonunu, aşağıdaki DataCamp Light bloğunda olduğu gibi hello() komutunu çalıştırarak çağırın:
Bir Python fonksiyonuna docstring nasıl eklenir
Python’da fonksiyon yazmanın bir diğer önemli yönü: docstring’ler. Docstring’ler, fonksiyonunuzun ne yaptığını, örneğin gerçekleştirdiği hesaplamaları veya döndürdüğü değerleri açıklar. Bu açıklamalar, fonksiyonunuzun belgeleri olarak hizmet eder; böylece fonksiyonunuzu okuyan herkes, tanımındaki tüm kodu takip etmek zorunda kalmadan fonksiyonunuzun ne yaptığını anlar.
Fonksiyon docstring’leri, fonksiyon başlığından hemen sonraki satıra yerleştirilir ve üç tırnak arasına yazılır. hello() fonksiyonunuz için uygun bir Docstring, ‘"Hello World" yazdırır’ olabilir.
def hello():
"""Prints "Hello World".
Returns:
None
"""
print("Hello World")
return
Not docstring’ler burada örnek olarak verilenin çok daha uzun olabilir. Docstring’leri daha ayrıntılı incelemek isterseniz, scikit-learn veya pandas gibi Python kütüphanelerinin Github depolarına göz atmanız en iyisidir; bolca örnek bulacaksınız!
Python’da fonksiyon argümanları
Az önce, parametreler ve argümanlar arasındaki farkı öğrendiniz. Kısaca, argümanlar herhangi bir fonksiyon veya metot çağrısına verilen değerlerdir; fonksiyon veya metot kodu ise argümanlara parametre adlarıyla atıfta bulunur. Python UDF’lerinin alabileceği dört tür argüman vardır:
- Varsayılan argümanlar
- Zorunlu argümanlar
- Anahtar sözcük (keyword) argümanları
- Değişken sayıda argüman
Varsayılan Argümanlar
Varsayılan argümanlar, fonksiyon çağrısı sırasında bir argüman değeri iletilmezse varsayılan bir değer alan argümanlardır. Bu varsayılan değeri, aşağıdaki örnekte olduğu gibi = atama operatörüyle belirleyebilirsiniz:
Zorunlu Argümanlar
İsminden de anlaşılacağı gibi, bir UDF’in zorunlu argümanları mutlaka bulunması gerekenlerdir. Bu argümanlar, fonksiyon çağrısı sırasında ve tam olarak doğru sırada iletilmelidir; aşağıdaki örnekte olduğu gibi:
a ve b parametrelerine karşılık gelen argümanlara ihtiyacınız vardır; aksi hâlde fonksiyonu hatasızçağıramazsınız. a ile b’nin yerini değiştirirseniz sonuç farklı olmayacaktır, ancak plus()’ı şu şekilde değiştirirseniz farklı olabilir:
Anahtar Sözcük Argümanları
Tüm parametreleri doğru sırada çağırdığınızdan emin olmak istiyorsanız, fonksiyon çağrınızda anahtar sözcük argümanlarını kullanabilirsiniz. Bunlarla argümanları parametre adlarıyla belirlersiniz. Bunu biraz daha netleştirmek için yukarıdaki örneği ele alalım:
Anahtar sözcük argümanlarını kullanarak parametrelerin sırasını da değiştirebileceğinizi ve fonksiyonunuzu çalıştırdığınızda yine aynı sonucu alacağınızı unutmayın:
Değişken Sayıda Argüman
Bir fonksiyona geçirmek istediğiniz argümanların tam sayısını bilmediğiniz durumlarda, *args ile şu söz dizimini kullanabilirsiniz:
Yıldız işareti (*), anahtar sözcük olmayan tüm değişken argümanların değerlerini tutan değişken adının önüne konur. Burada *varint, *var_int_args veya başka herhangi bir adı da plus() fonksiyonuna iletebileceğinizi unutmayın.
İpucu: *args’ı yıldız içeren başka bir adla değiştirmeyi deneyin. Yukarıdaki kodun çalışmaya devam ettiğini göreceksiniz!
Yukarıdaki fonksiyonun, plus()’a geçirilen tüm argümanları toplamaya yarayan yerleşik Python sum() fonksiyonunu kullandığını görüyorsunuz. Bunu kullanmaktan kaçınmak ve fonksiyonu tamamen kendiniz yazmak isterseniz, şu alternatifi kullanabilirsiniz:
Global ve yerel değişkenler
Genel olarak, bir fonksiyon gövdesi içinde tanımlanan değişkenlerin yerel kapsamı (local scope) vardır; dışarıda tanımlananların ise global kapsamı (global scope) vardır. Bu, yerel değişkenlerin bir fonksiyon bloğu içinde tanımlandığı ve yalnızca o fonksiyon içinde erişilebildiği, global değişkenlerin ise betiğinizdeki tüm fonksiyonlar tarafından erişilebilir olduğu anlamına gelir:
Fonksiyon gövdesi içinde tanımlanmış yerel değişken total’ı yazdırmaya çalıştığınızda name 'total' is not defined diyen bir NameError alacağınızı göreceksiniz. Öte yandan init değişkeni sorunsuzca yazdırılabilir.
Python’da Anonim Fonksiyonlar
Anonim fonksiyonlar, Python’da lambda fonksiyonları olarak da adlandırılır; çünkü standart def anahtar sözcüğüyle bildirmek yerine lambda anahtar sözcüğünü kullanırsınız.
Yukarıdaki DataCamp Light bloğunda lambda x: x*2 anonim ya da lambda fonksiyonudur. x argümandır ve x*2 değerlendirilen ve döndürülen ifade ya da yönergedir. Bu fonksiyonu özel kılan, bu eğitimde ilk bölümde gördüğünüz örneklerin aksine bir ada sahip olmamasıdır. Yukarıdaki fonksiyonu bir UDF olarak yazmak zorunda olsaydınız, sonuç şöyle olurdu:
def double(x):
return x*2
İki argümanla çalıştığınız bir başka lambda fonksiyonu örneğini ele alalım:
Anonim fonksiyonları, kısa bir süre için isimsiz bir fonksiyona ihtiyaç duyduğunuz ve çalışma zamanında oluşturulan durumlarda kullanırsınız. Bunun anlamlı olduğu belirli bağlamlar, filter(), map() ve reduce() ile çalışırken ortaya çıkar:
filter() fonksiyonu, adının da ima ettiği gibi, orijinal my_list giriş listesini >10 ölçütüne göre filtreler. map() ile ise listedeki tüm öğelere bir fonksiyon uygularsınız. Bu durumda tüm elemanları 2 ile çarparsınız.
reduce() fonksiyonunun functools kütüphanesinin bir parçası olduğunu unutmayın. Bu fonksiyonu my_list listesinin öğelerine, soldan sağa kümülatif olarak uygular ve diziyi tek bir değere indirgersiniz; bu örnekte bu değer 55’tir.
Python’da main() Fonksiyonunu Kullanma
Java gibi diğer programlama dillerinde deneyiminiz varsa, fonksiyonların yürütülmesi için main fonksiyonunun gerekli olduğunu bilirsiniz. Yukarıdaki örneklerde gördüğünüz gibi, Python’da bu zorunlu değildir. Ancak Python programınıza bir main() fonksiyonu eklemek, kodunuzu mantıksal olarak yapılandırmak için kullanışlı olabilir — en önemli bileşenlerin tümü bu main() fonksiyonu içinde toplanır.
Bir main() fonksiyonunu kolayca tanımlayabilir ve yukarıdaki diğer tüm fonksiyonlarda yaptığınız gibi çağırabilirsiniz:
Ancak mevcut hâliyle, modül olarak içe aktardığınızda main() fonksiyonunuzun kodu çağrılacaktır. Bunun olmasını engellemek için, __name__ == '__main__' olduğunda main() fonksiyonunu çağırırsınız.
Bu, yukarıdaki kod bloğunun şu hâle geleceği anlamına gelir:
Not __main__ fonksiyonunun yanı sıra, bir sınıfın ya da nesnenin örneğini başlatan bir __init__ fonksiyonunun da bulunduğunu unutmayın. Basitçe ifade etmek gerekirse, bu bir kurucu (constructor) ya da başlatıcı (initializer) görevi görür ve bir sınıfın yeni bir örneğini oluşturduğunuzda otomatik olarak çağrılır. Bu fonksiyonla, yeni oluşturulan nesne, bu eğitimde daha önce gördüğünüz self parametresine atanır. Aşağıdaki örneğe bakın:
class Dog:
"""
Requires:
legs - Legs so that the dog can walk.
color - A color of the fur.
"""
def __init__(self, legs, color):
self.legs = legs
self.color = color
def bark(self):
bark = "bark" * 2
return bark
if __name__ == "__main__":
dog = Dog(4, "brown")
bark = dog.bark()
print(bark)
Python Fonksiyonlarını Pratik Etmeye Devam Edin
Tebrikler! Python’da fonksiyonlar üzerine bu kısa eğitimi tamamladınız. Diğer temel Python programlama materyallerini gözden geçirmek isterseniz, Veri Bilimi için Veri Tipleri kursunu kaçırmayın; burada listeler, sözlükler, demetler (tuple), kümeler ve tarih-saat konularındaki bilginizi pekiştirip pratik yapacaksınız.
Python Fonksiyonları Hakkında Sık Sorulan Sorular
Python’da fonksiyon nedir?
Fonksiyon, belirli bir görevi yerine getiren, yeniden kullanılabilir bir kod bloğudur. Girdiler alabilir, bunları işler ve çıktılar döndürebilir.
Python’da fonksiyon nasıl tanımlanır?
Python’da bir fonksiyon tanımlamak için def anahtar sözcüğünü kullanın, fonksiyonunuza bir ad verin, parantez içinde isteğe bağlı parametreler ekleyin, kodunuzu yazın ve isteğe bağlı olarak bir değer return edin.
Python’da fonksiyonlar ve metotlar arasındaki fark nedir?
Fonksiyonlar bağımsızdır, metotlar ise sınıflara aittir. Tüm metotlar fonksiyondur ancak tüm fonksiyonlar metot değildir.
Python’da fonksiyon türleri nelerdir?
Python’da yerleşik fonksiyonlar (ör. print()), kullanıcı tanımlı fonksiyonlar (kendi oluşturduklarınız) ve anonim fonksiyonlar (kısa ömürlü lambda fonksiyonları) vardır.
Parametreler ve argümanlar arasındaki fark nedir?
Parametreler, fonksiyon tanımındaki yer tutuculardır; argümanlar ise fonksiyonu çağırırken aktardığınız gerçek değerlerdir.
Lambda fonksiyonu nedir?
Lambda fonksiyonu, hızlı işler için kullanılan tek satırlık, isimsiz bir fonksiyondur.
__main__ fonksiyonunu neden kullanırız?
__main__ fonksiyonu, kodunuzu düzenli tutar ve belirli kısımların yalnızca betik doğrudan çalıştırıldığında, içe aktarıldığında ise çalıştırılmamasını sağlar.
Global ve yerel değişkenler arasındaki fark nedir?
Global değişkenler her yerden erişilebilirken, yerel değişkenler yalnızca ait oldukları fonksiyon içinde yaşar.