# Python'da fonksiyonlar: def, return, argümanlar, *args ve **kwargs, lambda ve tür ipuçları

URL: https://skillaria.top/tr/guides/python/python-fonksiyonlar

Python'da fonksiyon, bir isme sahip ve parantezle çağrılan kod bloğudur; def ile tanımlanır ve sonucunu return ile döndürür, return yoksa None döner. Argümanlar sırayla ya da isimle verilebilir; *args fazla konumsal değerleri bir demete, **kwargs adlandırılmış değerleri bir sözlüğe toplar, lambda ise tek ifadelik kısa bir isimsiz fonksiyon oluşturur.

Python'da fonksiyon, bir isimle tanımlanan ve istediğiniz kadar farklı girdiyle çağırabileceğiniz bir kod parçasıdır. `def` anahtar sözcüğüyle tanımlanır, değerleri parametreler üzerinden alır ve sonucu `return` ile verir. Python'da fonksiyonlar, uzun bir betiği anlaşılır ve test edilebilir adımlara bölmenin ana yoludur.

## Fonksiyon nasıl tanımlanır: def

Tanım `def` ile başlar; ardından ad, parantez içinde parametreler ve iki nokta gelir. Gövde dört boşluk girintiyle yazılır: girinti Python'da bir süs değil, sözdiziminin parçasıdır.

```
def greet(name):
    """Kullanıcı için bir karşılama metni döndürür."""
    return f"Merhaba, {name}!"

print(greet("Ayşe"))   # Merhaba, Ayşe!
```

Başlığın hemen altındaki üç tırnaklı metin docstring'dir, yani fonksiyonun belgesidir. `help(greet)` bunu gösterir, editörler de ipucu olarak kullanır. Fonksiyon adları PEP 8 gereği snake_case biçiminde yazılır: `add_expense`, `get_rate`.

`def greet(name):` satırına fonksiyonun imzası (signature) denir: ad ve parametre listesi, varsa tür ipuçlarıyla birlikte. İmzaya bakan okur, gövdeyi okumadan fonksiyonun nasıl çağrılacağını anlar.

## Python'da return ne yapar

`return` fonksiyonu bitirir ve değeri çağırana verir. `return` çalıştıktan sonraki kodlar işletilmez. `return` yoksa ya da değersiz yazılmışsa fonksiyon `None` döndürür.

```
def area(w, h):
    w * h          # sonuç hesaplandı ama atıldı

print(area(3, 4))  # None

def area(w, h):
    return w * h

print(area(3, 4))  # 12
```

Unutulmuş `return`, yeni başlayanların en sık hatalarından biridir: fonksiyon "çalışır" gibi görünür ama `None` döndürür ve hata bir satır sonra ortaya çıkar. Birden fazla değer de döndürebilirsiniz; aslında bu tek bir demettir ve kolayca açılabilir:

```
def min_max(numbers):
    return min(numbers), max(numbers)

low, high = min_max([4, 1, 9])
print(low, high)   # 1 9
```

Erken `return`, gereksiz iç içe bloklardan kurtulmanıza yardım eder: önce özel durumları ayıklayın, sonra asıl mantığı yazın.

```
def discount(price, is_member):
    if price  dict[str, object]:
    return {"title": title, "amount": amount, "category": category}

def area(w: float, h: float) -> float:
    w * h   # mypy: Missing return statement
```

Denetimi kurulum gerektirmeden `uvx mypy .` ile çalıştırabilirsiniz. Yukarıdaki örnek tür ipuçlarının faydasını gösteriyor: `-> float` ile yazılmış fonksiyonda unutulan `return`'ü analiz aracı hemen yakalar.

Python 3.12'den itibaren (PEP 695) genel fonksiyonlar `TypeVar` olmadan yazılır: tür parametresi köşeli parantez içinde verilir, tür takma adı ise `type` anahtar sözcüğüyle tanımlanır.

```
def first[T](xs: list[T]) -> T:
    return xs[0]

type Money = int | float
```

Python 3.14'te (PEP 649) tür ipuçları tembel hâle geldi: ilk erişildiğinde hesaplanırlar. Bu sayede aşağıda tanımlanan bir sınıfa tırnaksız başvurabilirsiniz ve `from __future__ import annotations` satırına artık gerek yoktur.

## "Verilmedi" ile "None verildi" ayrımı: Python 3.15'te sentinel

Varsayılan `None` değeri, argümanın hiç verilmediğiyle bilerek `None` verildiğini ayırt etmeye yetmez. Yıllardır bu sorun el yapımı bir işaretçiyle çözülüyordu:

```
_MISSING = object()

def get_rate(currency, default=_MISSING):
    rates = {"USD": 90.5}
    if currency in rates:
        return rates[currency]
    if default is _MISSING:
        raise KeyError(currency)
    return default
```

Python 3.15 ile PEP 661 gereği yerleşik `sentinel` fonksiyonu geldi: `MISSING = sentinel("MISSING")` okunaklı bir gösterimi olan benzersiz bir işaretçi oluşturur; kopyalandığında kendisi kalır, pickle ile serileştirilir ve `float | MISSING` gibi bir tür ipucunda kullanılabilir. Eski sürümlerde `object()` ile yapılan yöntem çalışmaya devam eder.

## Fonksiyonlarda tipik hatalar

- **return unutmak** — fonksiyon `None` döndürür.
- **Parantezi unutmak** — `print(greet)` sonucu değil, fonksiyon nesnesini yazdırır.
- **Değiştirilebilir varsayılan değer** — tüm çağrılar için ortak liste.
- **Yanlış argüman sayısı** — `TypeError: greet() missing 1 required positional argument: 'name'`.
- **Yerleşik bir adla çakışma** — `list` ya da `sum` adında bir fonksiyon, yerleşik fonksiyonu gölgeler.

## Özet

Python'da fonksiyonlar `def` ile tanımlanır, sonucu `return` ile döndürür ve argümanları sırayla ya da isimle alır. `*args` ve `**kwargs` esneklik sağlar, `/` ve `*` çağrıyı katılaştırır, lambda tek kullanımlık fonksiyonlar için kısalık sağlar, tür ipuçları ise mypy ile birlikte hataları çalıştırmadan yakalar. Kursta bu konu uygulamalı işlenir: harcama takipçisi, tür ipuçlu fonksiyonlara bölünür ve mypy ile denetlenir.

## FAQ

**Parametre ile argüman arasındaki fark nedir?**

Parametre fonksiyonun tanımındaki isimdir; argüman çağrıda verilen somut değerdir. def greet(name) içindeki name parametredir, greet("Ayşe") çağrısındaki "Ayşe" ise argümandır.

**Bir fonksiyonu tanımlanmadan önce çağırabilir miyim?**

Modül düzeyinde hayır: def satırı önce çalışmalıdır, yoksa NameError alırsınız. Başka bir fonksiyonun içinde ise, çağrı tanım çalıştıktan sonra olduğu sürece, aşağıda tanımlanan bir fonksiyonu çağırabilirsiniz.

**Bir fonksiyon kaç değer döndürebilir?**

Teknik olarak bir değer; ama bu değer bir demet olabilir: return a, b iki elemanlı bir demet döndürür ve x, y = f() ile açılır.

**Tür ipuçlarını yazmak zorunlu mu?**

Hayır, Python onlarsız da çalışır. Ancak başkalarının okuyacağı kodda tür ipuçları bakımı kolaylaştırır ve mypy ya da pyright hataları çalıştırmadan bulur.

**lambda içinde if kullanabilir miyim?**

Yalnızca koşullu ifade kullanabilirsiniz: lambda x: "çift" if x % 2 == 0 else "tek". Lambda içinde komutlar, döngüler ve atamalar kullanılamaz.


---
Source: Skillaria.Top (https://skillaria.top)
