Links
Comment on page
🔮

Fonksiyonlar

Python üzerinde fonksiyonlar ve metotlar

👀 Hızlı Bakış

  • 👬 Fonksiyonlara değişken değerlerinin kopyası gönderilir
  • 💁‍♂️ Parametre olarak aldıkları objelerin içeriğini değiştirebilirler, ama kendisini değiştiremezler
  • ✨ Parametre değerleri tanımlandıkları anda atanır, her çağırıldığında değil
  • ⚡ Varsayılan parametre değerleri değiştirilemez değerler olmalıdır, aksi halde sorunlar oluşur
‍‍🧙‍♂ Detaylı bilgi için 📖 Mutable Default Arguments alanına bakabilirsin.

✨ Oluşturma

  • 🆔 Fonksiyon ismi eşsiz olmalıdır, override yapısını python desteklemez
  • 💎 Parametreler tip belirtmeden de yazılabilir
  • 📝 Dokümantasyon için fonksiyonun tanımlandığı satırın altına """ karakterleri arasına içerik yazılır
  • return yapısı ile sonuçlarını döndürürler
📢 Kodların derlenme yapısı yukarıdan aşağı olduğu için fonksiyonlar, yukarıda (önceden) tanımlanmadan kullanılamaz.
🧱 Fonksiyon Temeli
⭐ Örnek
📜 Dökümantasyon
def function_name(parameters):
"""docstring"""
statement(s)
def greet(name: str) -> str:
"""This function greets to
the person passed in as
parameter"""
return "Hello, " + name + ". Good morning!"
>>> print(greet.__doc__)
This function greets to
the person passed into the
name paramete

💎 Parametreler

  • ⚡ Fonksiyonlar tanımlandığı vakit varsayılan atamalar yapılır.
  • 🚄 *args, **kwargs şeklinde list ve dict elemanları alan parametreler tanımlanabilir
  • 🆔 Parametre tipler param: type şeklinde belirtiliebilir ama zorunlu değildir
‍🧙‍♂ Detaylı bilgi için Function Parameter Types in Python yazısına bakabilirsin.
🎌 Varsayılan Parametre
🏳‍🌈 Keyfi Parametre
🐥 Tip Tanımlama
def greet(name, msg = "Good morning!"):
"""
This function greets to
the person with the
provided message.
If message is not provided,
it defaults to "Good
morning!"
"""
print("Hello",name + ', ' + msg)
greet("Kate") # Varsayılan parametreyi kullanma
greet("Bruce","How do you do?") # Sıralı parametre verme
greet("Bruce", msg="Naber") # İşaretleyerek paremetre verme
# * ön eki ile ile kaç tane isim gelirse o kadar kullanıyoruz.
def greet(*names):
"""This function greets all
the person in the names tuple."""
# names is a tuple with arguments
for name in names:
print("Hello",name)
greet("Monica","Luke","Steve","John")
from type import Tuple, List
from pathlib import Path
def foo(root: Path, exbool=False, msg: str) -> Tuple[List, List]:
...
return ["temp"], ["temp"]
👬 Değişkenlerin Kopyasının Gönderilmesi
✨ Değişken İçeriğinin Güncellenmesi
💎 Varsayılan Parametrelerdeki Değişken Sorunu
# Değerlerin kopyalanması
def increase(a):
return a + 2
a = 5
b = increase(a) # 7
print(a) # 5
class Home:
name: str
age: int
def __init__(self, name: str, age: int):
self.name = name
self.age = age
def make_older(home: Home):
home.age += 1
def new_home(home: Home):
home = Home(home.name, home.age + 1)
myhome = Home("Any", 10)
# Değişkenlerin kopyası aktarılsa dahi içerikleri aynı olduğu için
# değiştirilebilirler
make_older(myhome)
myhome.age # 11
# Değişkenlerin kopyası aktarıldığı için home değerininin kopyası değiştirilmekte,
# aslı kalmaktadır
new_home(myhome)
myhome.age # 11
# Parametre varsayılan değeri olarak list atanıyor
def append_to(element, to=[]):
to.append(element)
return to
# list içerisine 12 değeri ekleniyor
my_list = append_to(12)
print(my_list) # [12]
# Yine aynı list içerisine 42 ekleniyor ve artık 12,42 değeri oluşuyor
# Parametre değerleri tek seferlik atandığından [] objesinin adresi to
# değişkenine atanır, list her değiştiğinde to içeriği de değişir halde
# olacaktır
my_other_list = append_to(42)
print(my_other_list) # [12, 42]

♿ Erişebilirlik

  • 🙄 Python üzerinde private ve public yapısı derleyici tarafından kontrol edilmez
  • ⚖️ Kodun anlaşılabilirliği artırmak için programcılar tarafından belirlenen kurallardır
  • 🌫️ __ ile başlayan fonksiyonlar private olarak algılanır, sınıf dışında önerilerde gözükmezler
  • 🌃 _ ile başlayan fonksiyonlar dosya içinde public dosya dışında private olarak ifade edilir (interval)

🧱 Türler

💫 Özyineleyen (recursion)
🎌 Lambda
🏰 İç İçe
📁 Alt Fonksiyonlar
def calc_factorial(x):
"""This is a recursive function
to find the factorial of an integer"""
if x == 1:
return 1
else:
return (x * calc_factorial(x-1))
num = 4
print("The factorial of", num, "is", calc_factorial(num))
calc_factorial(4) # 1st call with 4
4 * calc_factorial(3) # 2nd call with 3
4 * 3 * calc_factorial(2) # 3rd call with 2
4 * 3 * 2 * calc_factorial(1) # 4th call with 1
4 * 3 * 2 * 1 # return from 4th call as number=1
4 * 3 * 2 # return from 3rd call
4 * 6 # return from 2nd call
24 # return from 1st call

💚 Özyineleyen Fonksiyonların Avantajları

  • Özyineleyen fonksiyonlar kodun daha temiz ve zarif gözükmesini sağlar
  • Karmaşık bir görev alt görevlere ayrılarak rahat çözülebilir
  • İç içe döngülere göre daha iyidir

💔 Özyineleyen Fonksiyonların Zararları

  • Bazı durumlarda anlaşılabilmesi zordur
  • Uzun tekrarlarda çok fazla vakit ve zaman harcarlar
  • Hata ayıklama oldukça zordur
double = lambda x: x * 2 # lambda fonksiyon
def double(x): # Fonksiyon
return x * 2

Filter ile Lambda Kullanımı

Sadece koşulu sağlayan değerleri döndürür.
listem = [1, 5, 4, 6, 8, 11, 3, 12]
cift_listem = list(filter(lambda x: (x%2 == 0) , listem))
print(cift_listem) # [4, 6, 8, 12]

Map ile Lambda Kullanımı

Her eleman için işlem yapar.
listem = [1, 5, 4, 6, 8, 11, 3, 12]
katlanmis_listem = list(map(lambda x: x * 2 , listem))
print(katlanmis_listem) # Output: [2, 10, 8, 12, 16, 22, 6, 24]
  • Python ile fonksiyon içinde fonksiyon tanımlamak mümkündür.
  • İç içe fonksiyonlarda parametreler ortak kullanılır
Kodların derlenme yapısı yukarıdan aşağı olduğu için fonksiyonlar yukarıda (önceden) tanımlanmadan kullanılamaz.
def func1(param):
# func2() bu alanda kullanılamaz
def func2():
# Parametreler ortak kullanıldığından ek olarak almasına gerek yoktur
print("2.", param)
print(param)
func2() # Bu alanda ekrana '2.Selam' basar
func1("Selam")

🤯 Karmaşık İç İçe Fonksiyon

def foo():
bar()
def bar():
foo()
Objelerin ve sınıfların alt fonksiyonlarını dir(<obj>) metodu ile görüntüleyebiliriz.
dir("X") # String metodlarını listeler
dir([]) # List metodlarını listeler
dir(<class>) # Class metodlarını listeler

🌇 Global, Local ve Nonlocal

❔ Nedir
⭐ Örnek
🌍 Global Değişken İşlemleri
💥 Ek Örnek
Kavram
Açıklama
Erişim
global
Tüm modülde geçerli değişkenler
Okuma
local
Fonksiyonların içerisindeki yerel değişkenler
Okuma ve Yazma
nonlocal
Modül ile fonksiyon arasında kalan, genellikle iç içe fonksiyonlarda kullanılan değişkenler
x = 5 # Global değişken
def func1(param):
x = 4 # Nonlocal değişken
def func11():
x = 1 # Local değişken
# print(param)
# Otomatik olarak üst fonksiyonun parametresini ele alır
# print(param)
# param = 5
# Yukarıdaki işlemde param'a atama yapıldığından `local param` olarak tanımlanır.
# Print içindeki param tanımlanmadan kullanılmaktadır, bu sebeple `print(param)` komutu çalışmaz hata verir.
# param tanımlanmadan kullanıldı (`nonlocal param` olarak yazılması lazım)
print(x)
# Python otomatik olarak `global x` deyimini kullanır
# x'i global değişkenlerde arar ve ekrana '5' basar
# print(x)
# x = 3
# Yukarıdaki işlemde x'e atama yapıldığından `local x` olarak tanımlanır.
# Print içindeki x tanımlanmadan kullanılmaktadır, bu sebeple `print(x)` komutu çalışmaz hata verir.
# x tanımlanmadan kullanıldı (`global x` olarak yazılması lazım)
global x
print(x)
x = 3
print(x)
x = 5
def xDegistir():
x = 3 # Yerel x değişkenine 3 değeri atanır, evrensel x değişmez.
def globalXDegistir():
global x
x = 4 # Evrensel x değişir
def scope_test():
def do_local():
spam = "local spam"
def do_nonlocal():
nonlocal spam
spam = "nonlocal spam"
def do_global():
global spam
spam = "global spam"
spam = "test spam"
do_local()
print("After local assignment:", spam)
do_nonlocal()
print("After nonlocal assignment:", spam)
do_global()
print("After global assignment:", spam)
scope_test()
print("In global scope:", spam)
# After local assignment: test spam
# After nonlocal assignment: nonlocal spam
# After global assignment: nonlocal spam
# In global scope: global spa

🏃‍♂️ Hız Hakkında

  • Fonksiyonlarda işlem yapılma hızı, manuel (kod satırı olarak) işlem yapılmasından daha hızlıdır.
  • ~%80 daha hızlı çalıştığını script üzerinden görebilirsiniz
  • Bu değer bilgisayar donanımınıza göre değişiklik gösterecektir
  • Hafızayı (memorial) kullanan fonksiyonlar tekrarlı (recursive) fonksiyonlardan daha hızlıdır.
⏱ Hız Ölçme
📋 Çıktı
from time import time
# Obje uzunluğu
RANGE = 1000
# Toplam test sayısı
TEST_RANGE = 10000
# Fonksiyonun yavaş kaldığı testlerin sayısı
func_slow_count = 0
# Objeyi oluşturma
data1 = [i for i in range(RANGE)]
data2 = [i for i in range(RANGE)]
data3 = [i for i in range(RANGE)]
avg_func_speed = 0
for test in range(TEST_RANGE):
first_time = time()
# Normal işleme
data = []
for test2 in range(len(data1)):
data.append(data1[test2])
for test2 in range(len(data2)):
data.append(data2[test2])
for test2 in range(len(data3)):
data.append(data3[test2])
normal_time = time() - first_time
# Fonksiyon ile işleme
def fdata(data1, data2, data3):
data = []
for test2 in range(len(data1)):
data.append(data1[test2])
for test2 in range(len(data2)):
data.append(data2[test2])
for test2 in range(len(data3)):
data.append(data3[test2])
return data
data = [i for i in range(RANGE)]
first_time = time()
# Fonksiyon ile veri atama
fdata = fdata(data1, data2, data3)
func_time = time() - first_time
if normal_time - func_time < 0:
func_slow_count += 1
avg_func_speed = (
avg_func_speed * test + (normal_time / func_time - 1) * 100
) / (test + 1)
print("Fonksiyon işlemi normalden %" + "%.2f daha hızlı, testlerde " % avg_func_speed + "%" + "%.2f ihtimalle yavaş kalmıştır." %
(func_slow_count * 100 / TEST_RANGE))
# Colab çıktıları
Fonksiyon işlemi normalden %47.32 daha hızlı, testlerde %0.09 ihtimalle yavaş kalmıştır.
Fonksiyon işlemi normalden %46.86 daha hızlı, testlerde %0.21 ihtimalle yavaş kalmıştır.
Fonksiyon işlemi normalden %52.29 daha hızlı, testlerde %0.31 ihtimalle yavaş kalmıştır.
Fonksiyon işlemi normalden %48.02 daha hızlı, testlerde %0.41 ihtimalle yavaş kalmıştır.
Fonksiyon işlemi normalden %46.89 daha hızlı, testlerde %0.53 ihtimalle yavaş kalmıştır.
Fonksiyon işlemi normalden %46.73 daha hızlı, testlerde %0.68 ihtimalle yavaş kalmıştır.
Fonksiyon işlemi normalden %47.21 daha hızlı, testlerde %0.86 ihtimalle yavaş kalmıştır.
Fonksiyon işlemi normalden %47.02 daha hızlı, testlerde %1.09 ihtimalle yavaş kalmıştır.
Fonksiyon işlemi normalden %47.60 daha hızlı, testlerde %1.27 ihtimalle yavaş kalmıştır.
Fonksiyon işlemi normalden %52.76 daha hızlı, testlerde %1.41 ihtimalle yavaş kalmıştır.
Fonksiyon işlemi normalden %48.76 daha hızlı, testlerde %1.74 ihtimalle yavaş kalmıştır.
Fonksiyon işlemi normalden %46.28 daha hızlı, testlerde %1.90 ihtimalle yavaş kalmıştır.
Fonksiyon işlemi normalden %46.94 daha hızlı, testlerde %2.11 ihtimalle yavaş kalmıştır.
Fonksiyon işlemi normalden %46.21 daha hızlı, testlerde %2.25 ihtimalle yavaş kalmıştır.
Fonksiyon işlemi normalden %46.50 daha hızlı, testlerde %2.39 ihtimalle yavaş kalmıştır.
Fonksiyon işlemi normalden %52.01 daha hızlı, testlerde %2.49 ihtimalle yavaş kalmıştır..

💠 Dahili ve Harici Fonksiyonlar

  • Dahili fonksiyonlar, python ile gelen hazır fonksiyonlardır ve direkt olarak kullanılabilirler
  • Harici fonksiyonları kullanmadan önce import <paket> ile paketi dahil etmeniz lazım
  • Fonksiyonların kullanımı <paket>.<fonksiyon> şeklindedir
Fonksiyon
Açıklama
Örnek
Çıktı
print(<string>)
Ekrana yazma
print("X: {1}, Y: {2}")
X: {1}, Y: {2}
print('\r' + <string>, end='')
Satır başına yazı yazma
sum, len
Toplama, uzunluk, ortalama
sum([1, 2, 3])
5
eval(<string>)
Verilen stringi hesaplama
eval("x + 5")
6
type(<obje>)
Objenin türünü bulma
type(x)
<class 'number'>
enumerate(<obje>, <si>)
Numaralandırma
i, line in enumerate(file, 0)
Metin Karakterlerini Sayma
Dosya Satırlarını a
Alt Fonksiyonları Listeleme
string = "Yemreak"
for i, char in enumerate(string):
print(i, char)
# 0 Y
# 1 e
# 2 m
# ...
with open(FILE, "r") as file:
for i, line in enumerate(file, a):
print(f"{i}. {line}")
# a. satır
# (a+1). satır
# ...
dir(<func | modul>)
2023 © Yunus Emre AK