Size daha iyi hizmet sunabilmek için çerezleri kullanıyoruz.
Web sitemizde gezinme deneyiminizi geliştirmek, size kişiselleştirilmiş içerik ve hedefli reklamlar göstermek, web sitesi trafiğimizi analiz etmek ve ziyaretçilerimizin nereden geldiğini anlamak için çerezleri ve diğer izleme teknolojilerini kullanıyoruz.
⚠️
KVKK ve Çerez Politikası Bilgilendirmesi
6698 sayılı Kişisel Verilerin Korunması Kanunu (KVKK) ve Aydınlatma Yükümlülüğü kapsamında; web sitemizin temel fonksiyonlarının çalışabilmesi, veri güvenliğinin sağlanması ve performans analizi yapılabilmesi için zorunlu çerezlerin kullanımı gerekmektedir. Çerez kullanımını reddetmeniz halinde, teknik imkansızlıklar ve veri senkronizasyonu kesintileri nedeniyle web sitemizdeki hizmetlerden yararlanmanız mümkün olmamaktadır. Sitemizdeki içeriklere erişebilmek için çerez kullanımını onaylamanız gerekmektedir.
Python ile Yazılım Geliştirme — Başlangıçtan Uzmanlığa Kapsamlı Teknik Rehber
Python, 1991 yılında Guido van Rossum tarafından yayımlanan ve bugün dünyanın en yaygın kullanılan programlama dillerinden biri haline gelen bir dil. TIOBE endeksinde sürekli olarak ilk üçte yer alıyor; veri bilimi, web geliştirme, otomasyon, yapay zeka gibi birbirinden farklı alanlarda fiilen endüstri standardı konumunda. Bu popülariteyi sağlayan şeyin sözdizimiyle başlamak doğru olur: Python, İngilizce’ye yakın, okunabilir bir yapıya sahip. Ama bu sadelik, dilin altında yatan gücü gizlemez. C uzantılarıyla entegrasyon, asenkron programlama desteği, kapsamlı standart kütüphane ve devasa ekosistem — bunların tamamı Python’u gerçek anlamda çok katmanlı bir dil yapıyor.
Şekil 1: Python ile Yazılım Geliştirme — Başlangıçtan Uzmanlığa Kapsamlı Teknik Rehber
Bölüm 1 — Kurulum, Ortam ve İlk Adımlar
Python Sürüm Yönetimi
Python kurulumu için doğrudan python.org üzerinden indirme yapılabilir. Ancak profesyonel kullanımda birden fazla Python sürümüyle çalışmak zorunlu hale gelir. Bunun için pyenv aracı son derece kullanışlı:
# pyenv kurulumu (Linux/macOS)curl https://pyenv.run | bash
# Kullanılabilir Python sürümlerini listelepyenv install --list
# Belirli bir sürümü kurpyenv install 3.12.3
# Global sürüm belirlepyenv global 3.12.3
# Proje bazlı sürüm belirlepyenv local 3.11.8
Windows kullanıcıları için pyenv-win paketi aynı işlevi görür.
Sanal Ortam Yönetimi
Her proje kendi bağımlılıklarını izole bir ortamda taşımalıdır. Python’un yerleşik venv modülü bu iş için yeterlidir:
Daha gelişmiş bağımlılık yönetimi için poetry veya uv tercih edilebilir. uv, Rust ile yazılmış ve son derece hızlı bir paket yöneticisi olarak öne çıkıyor:
# uv kurulumupip install uv
# Yeni proje oluşturuv init myproject
cd myproject
# Paket ekleuv add requests pandas
# Projeyi çalıştıruv run python main.py
IDE Seçimi
VS Code hafif ve genişletilebilir yapısıyla yaygın tercih. Python eklentisi, Pylance dil sunucusu ve Jupyter notebook desteği birlikte kullanıldığında güçlü bir ortam oluşuyor.
PyCharm ise tam özellikli bir IDE. Kod tamamlama, hata ayıklama, yeniden düzenleme araçları ve proje yönetimi entegre geliyor.
Jupyter Notebook / JupyterLab, özellikle veri analizi ve araştırma amaçlı çalışmalar için vazgeçilmez. Hücre bazlı çalıştırma modeli, adım adım keşif için idealdir:
pip install jupyterlab
jupyter lab
Bölüm 2 — Temel Sözdizimi ve Veri Tipleri
Değişkenler ve Dinamik Tipleme
Python dinamik olarak tiplendirilmiş bir dil; değişkenlere tip bildirimi yapmak zorunlu değil. Ancak Python 3.5’ten itibaren gelen tip ipuçları (type hints) okunabilirliği artırıyor ve statik analiz araçları için zemin hazırlıyor:
# Temel atamalarad: str ="Ahmet"yas: int =28maas: float =12500.75aktif: bool =True# Çoklu atamax, y, z =10, 20, 30# Değer takası — C/Java'dan farklı olarak geçici değişken gerekmezx, y = y, x
# Sabit benzeri değişkenler (Python'da gerçek sabit yok, konvansiyon büyük harf)MAX_BAGLANTI: int =100PI: float =3.14159265358979
# for — iterable üzerinde yinelememeyveler = ["elma", "armut", "kiraz", "üzüm"]
for meyve in meyveler:
print(meyve)
# enumerate — indeks ve değer birliktefor i, meyve in enumerate(meyveler, start=1):
print(f"{i}. {meyve}")
# rangefor i in range(1, 11, 2): # 1'den 10'a, 2'şer artarak print(i) # 1, 3, 5, 7, 9# whilesayac =0while sayac <5:
print(sayac)
sayac +=1# break ve continuefor n in range(20):
if n %2==0:
continue# çift sayıları atlaif n >15:
break# 15'ten büyük olunca dur print(n) # 1, 3, 5, 7, 9, 11, 13, 15# else bloğu (döngü tamamlanırsa çalışır, break ile durmazsa)for n in range(5):
if n ==10:
breakelse:
print("Döngü tamamlandı, break çalışmadı")
Bölüm 3 — Veri Yapıları
Listeler
Liste, Python’un en temel koleksiyon tipidir. Heterojen veri tutabilir ve değiştirilebilir (mutable):
# Liste oluşturmasayilar = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3]
karisik = [42, "Python", 3.14, True, None]
# Temel metotlarsayilar.append(7) # sona eklesayilar.insert(0, 0) # belirli indekse eklesayilar.remove(1) # ilk bulunan 1'i silcikarilan = sayilar.pop() # son elemanı çıkar ve döndürsayilar.sort() # sırala (yerinde)sirali = sorted(sayilar) # yeni sıralı liste döndürsayilar.reverse() # ters çevirprint(sayilar.count(5)) # 5'in kaç kez geçtiğiprint(sayilar.index(9)) # 9'un indeksi# Dilimlemeilk_uc = sayilar[:3]
son_uc = sayilar[-3:]
ters = sayilar[::-1]
# Liste birleştirmea = [1, 2, 3]
b = [4, 5, 6]
c = a + b # yeni listea.extend(b) # a'ya b'yi ekle# Kopyalama — dikkat!kopya_yanlis = sayilar # referans kopyası (aynı nesneye işaret)kopya_dogru = sayilar.copy() # yüzeysel kopyaderin_kopya = sayilar[:] # dilimleme ile kopyaimport copy
derin = copy.deepcopy(karisik) # iç içe nesneler için derin kopya
Demetler (Tuples)
Demetler immutable’dır. Değiştirilemezlik, veri bütünlüğü gerektiren senaryolarda ve dictionary anahtarı olarak kullanımda avantaj sağlar:
koordinat = (41.0082, 28.9784) # İstanbul koordinatlarırgb = (255, 128, 0)
# Parantez olmadan da demet oluşurnokta =10, 20# Tek elemanlı demet — virgül zorunlutekli = (42,)
# Demet açma (unpacking)enlem, boylam = koordinat
r, g, b = rgb
# Genişletilmiş açma (Python 3+)ilk, *orta, son = [1, 2, 3, 4, 5]
print(ilk) # 1print(orta) # [2, 3, 4]print(son) # 5# namedtuple — okunabilirliği artırırfrom collections import namedtuple
Nokta = namedtuple("Nokta", ["x", "y", "z"])
p = Nokta(1, 2, 3)
print(p.x, p.y, p.z) # 1 2 3print(p._asdict()) # {'x': 1, 'y': 2, 'z': 3}# dataclass ile daha modern alternatif (Python 3.7+)from dataclasses import dataclass
@dataclass(frozen=True) # frozen=True ile immutableclassKoordinat:
enlem: float
boylam: float
yukseklik: float =0.0ist = Koordinat(41.0082, 28.9784, 50)
print(ist)
Sözlükler (Dictionaries)
Python 3.7’den itibaren sözlükler ekleme sırasını korur. Hash tablosu üzerine inşa edilmiştir ve arama O(1) karmaşıklığındadır:
Python’da LEGB kuralı geçerlidir: Local → Enclosing → Global → Built-in
x ="global"defdis_fonksiyon():
x ="enclosing"defic_fonksiyon():
nonlocal x # enclosing kapsamındaki x'i değiştir x ="lokal" print(x) # lokal ic_fonksiyon()
print(x) # lokal (nonlocal etkiledi)defglobal_degistir():
global x
x ="değişti"dis_fonksiyon()
global_degistir()
print(x) # değişti
# Standart kütüphane örnekleriimport math
print(math.sqrt(144)) # 12.0print(math.pi) # 3.141592653589793print(math.log(1000, 10)) # 3.0print(math.factorial(10)) # 3628800import random
random.seed(42) # tekrarlanabilir sonuçlar içinprint(random.randint(1, 100))
print(random.choice(["elma", "armut", "kiraz"]))
random.shuffle(liste := [1, 2, 3, 4, 5])
from datetime import datetime, timedelta, date
simdi = datetime.now()
print(simdi.strftime("%d.%m.%Y %H:%M:%S"))
bir_hafta_sonra = simdi + timedelta(weeks=1)
dogum_gunu = date(1990, 5, 15)
bugun = date.today()
yas = (bugun - dogum_gunu).days //365import os
import pathlib
# Çalışma diziniprint(os.getcwd())
# Path işlemleri — pathlib önerilen yöntemp = pathlib.Path.home() /"Documents"/"proje"p.mkdir(parents=True, exist_ok=True)
# Dosya listesifor dosya in pathlib.Path(".").glob("**/*.py"):
print(dosya)
Bölüm 5 — İleri Seviye Konular
Hata Yönetimi
# Temel yapıtry:
sonuc =10/0exceptZeroDivisionErroras hata:
print(f"Sıfıra bölme hatası: {hata}")
except (TypeError, ValueError) as hata:
print(f"Tip veya değer hatası: {hata}")
exceptExceptionas hata:
print(f"Beklenmedik hata: {type(hata).__name__}: {hata}")
else:
print("Hata olmadı, sonuç:", sonuc)
finally:
print("Bu her zaman çalışır — temizlik işlemleri")
# Özel istisna sınıfıclassVeriDogrulamaHatasi(ValueError):
def__init__(self, alan: str, deger, mesaj: str =""):
self.alan = alan
self.deger = deger
super().__init__(mesaj orf"{alan} için geçersiz değer: {deger}")
defyas_dogrula(yas: int) ->None:
ifnot isinstance(yas, int):
raise VeriDogrulamaHatasi("yas", yas, "Yaş tamsayı olmalı")
if yas <0or yas >150:
raise VeriDogrulamaHatasi("yas", yas, "Yaş 0-150 aralığında olmalı")
try:
yas_dogrula(-5)
except VeriDogrulamaHatasi as e:
print(f"[{e.alan}] {e}")
# Context manager ile kaynak yönetimiclassBaglantiyiYonet:
def__enter__(self):
print("Bağlantı açıldı")
return self
def__exit__(self, tur, deger, traceback):
print("Bağlantı kapatıldı")
returnFalse# True dönerse istisna bastırılırwith BaglantiyiYonet() as baglanti:
print("İşlem yapılıyor...")
Dosya İşlemleri
# Metin dosyası yazmawith open("veri.txt", "w", encoding="utf-8") as f:
f.write("Birinci satır\n")
f.writelines(["İkinci satır\n", "Üçüncü satır\n"])
# Okumawith open("veri.txt", "r", encoding="utf-8") as f:
icerik = f.read() # tamamını oku f.seek(0)
satirlar = f.readlines() # liste olarak satırlar f.seek(0)
for satir in f: # satır satır yinele (büyük dosyalar için) print(satir.strip())
# Ekleme moduwith open("log.txt", "a", encoding="utf-8") as f:
from datetime import datetime
f.write(f"[{datetime.now():%Y-%m-%d %H:%M:%S}] Sistem başlatıldı\n")
# JSON işlemleriimport json
veri = {
"kullanicilar": [
{"id": 1, "ad": "Ali", "rol": "admin"},
{"id": 2, "ad": "Veli", "rol": "user"}
]
}
# Yazmawith open("kullanicilar.json", "w", encoding="utf-8") as f:
json.dump(veri, f, ensure_ascii=False, indent=2)
# Okumawith open("kullanicilar.json", "r", encoding="utf-8") as f:
yuklenen = json.load(f)
# CSV işlemleriimport csv
basliklar = ["ad", "soyad", "email", "yas"]
satirlar = [
["Ali", "Kaya", "ali@example.com", 30],
["Fatma", "Demir", "fatma@example.com", 25]
]
with open("kisiler.csv", "w", newline="", encoding="utf-8") as f:
yazar = csv.writer(f)
yazar.writerow(basliklar)
yazar.writerows(satirlar)
with open("kisiler.csv", "r", encoding="utf-8") as f:
okuyucu = csv.DictReader(f)
for satir in okuyucu:
print(satir["ad"], satir["email"])
List Comprehensions ve Generator Expressions
# List comprehensionkareler = [x**2for x in range(1, 11)]
# [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]# Filtreli comprehensioncift_kareler = [x**2for x in range(1, 11) if x %2==0]
# [4, 16, 36, 64, 100]# İç içe comprehensionmatris = [[i * j for j in range(1, 5)] for i in range(1, 5)]
# Dict comprehensionkelime_uzunluklari = {kelime: len(kelime) for kelime in ["python", "java", "rust", "go"]}
# {'python': 6, 'java': 4, 'rust': 4, 'go': 2}# Set comprehensionbenzersiz_uzunluklar = {len(k) for k in ["ali", "veli", "ay", "is"]}
# {2, 3, 4}# Generator expression — belleğe yüklemez, talep üzerine üretirtoplam = sum(x**2for x in range(1, 1000001)) # bellekte tek sayı tutar
Iterator ve Generator
# Manuel iteratorclassSayac:
def__init__(self, baslangic: int, bitis: int):
self.mevcut = baslangic
self.bitis = bitis
def__iter__(self):
return self
def__next__(self):
if self.mevcut >= self.bitis:
raiseStopIteration deger = self.mevcut
self.mevcut +=1return deger
for n in Sayac(1, 6):
print(n) # 1 2 3 4 5# Generator fonksiyonudeffibonacci(n: int):
"""n adet Fibonacci sayısı üretir.""" a, b =0, 1for _ in range(n):
yield a
a, b = b, a + b
for sayi in fibonacci(10):
print(sayi, end=" ")
# 0 1 1 2 3 5 8 13 21 34# Sonsuz generatordefsonsuz_artis(baslangic: int =0, adim: int =1):
n = baslangic
whileTrue:
yield n
n += adim
# itertools ile kullanimport itertools
gen = sonsuz_artis(0, 5)
ilk_10 = list(itertools.islice(gen, 10))
# [0, 5, 10, 15, 20, 25, 30, 35, 40, 45]# itertools kütüphanesiimport itertools
# Permütasyon ve kombinasyonprint(list(itertools.permutations([1, 2, 3], 2)))
print(list(itertools.combinations([1, 2, 3, 4], 2)))
# Gruplamaveriler = [
("A", 1), ("A", 2), ("B", 3), ("B", 4), ("C", 5)
]
veriler.sort(key=lambda x: x[0])
for grup, elemanlar in itertools.groupby(veriler, key=lambda x: x[0]):
print(grup, list(elemanlar))
Dekoratörler
import functools
import time
# Temel dekoratördefzamanlayici(fonksiyon):
@functools.wraps(fonksiyon)
defsarmalayici(*args, **kwargs):
baslangic = time.perf_counter()
sonuc = fonksiyon(*args, **kwargs)
bitis = time.perf_counter()
print(f"{fonksiyon.__name__} — {bitis - baslangic:.4f}s")
return sonuc
return sarmalayici
@zamanlayicidefagir_hesaplama(n: int) -> int:
return sum(i**2for i in range(n))
sonuc = agir_hesaplama(1000000)
# Parametre alan dekoratördeftekrar_dene(maks_deneme: int =3, bekleme: float =1.0):
defdekoratör(fonksiyon):
@functools.wraps(fonksiyon)
defsarmalayici(*args, **kwargs):
hatalar = []
for deneme in range(maks_deneme):
try:
return fonksiyon(*args, **kwargs)
exceptExceptionas hata:
hatalar.append(hata)
if deneme < maks_deneme -1:
time.sleep(bekleme)
raiseException(f"{maks_deneme} deneme başarısız: {hatalar[-1]}")
return sarmalayici
return dekoratör
@tekrar_dene(maks_deneme=3, bekleme=0.5)
defapi_cagri(url: str) -> dict:
import urllib.request
with urllib.request.urlopen(url) as resp:
return json.loads(resp.read())
# Önbellekleme (memoization)@functools.lru_cache(maxsize=128)
deffib_rekürsif(n: int) -> int:
if n <2:
return n
return fib_rekürsif(n -1) + fib_rekürsif(n -2)
print(fib_rekürsif(50)) # Önbellek olmadan çok yavaş olurduprint(fib_rekürsif.cache_info()) # CacheInfo(hits=48, misses=51, ...)
Bölüm 6 — Nesne Yönelimli Programlama
Sınıflar ve Nesneler
from dataclasses import dataclass, field
from typing import ClassVar
classBankaHesabi:
"""Basit banka hesabı implementasyonu."""# Sınıf değişkeni — tüm örneklerde ortak faiz_orani: ClassVar[float] =0.03def__init__(self, sahip: str, iban: str, bakiye: float =0.0):
self._sahip = sahip # "korumalı" (convention) self.__iban = iban # "özel" (name mangling) self._bakiye = bakiye
self._islem_gecmisi: list = []
# Property — kontrollü erişim@propertydefbakiye(self) -> float:
return self._bakiye
@propertydefsahip(self) -> str:
return self._sahip
# Metotlardefpara_yatir(self, miktar: float) ->None:
if miktar <=0:
raiseValueError("Yatırılacak miktar pozitif olmalı")
self._bakiye += miktar
self._islem_gecmisi.append(f"Yatırma: +{miktar:.2f} TL")
defpara_cek(self, miktar: float) ->None:
if miktar <=0:
raiseValueError("Çekilecek miktar pozitif olmalı")
if miktar > self._bakiye:
raiseValueError("Yetersiz bakiye")
self._bakiye -= miktar
self._islem_gecmisi.append(f"Çekme: -{miktar:.2f} TL")
deffaiz_uygula(self) ->None:
faiz = self._bakiye * self.faiz_orani
self._bakiye += faiz
self._islem_gecmisi.append(f"Faiz: +{faiz:.2f} TL")
# Dunder (magic) metotlardef__str__(self) -> str:
returnf"BankaHesabi({self._sahip}, {self._bakiye:.2f} TL)"def__repr__(self) -> str:
returnf"BankaHesabi(sahip={self._sahip!r}, bakiye={self._bakiye})"def__len__(self) -> int:
return len(self._islem_gecmisi)
@classmethoddeffaiz_guncelle(cls, yeni_oran: float) ->None:
cls.faiz_orani = yeni_oran
@staticmethoddefiban_dogrula(iban: str) -> bool:
return iban.startswith("TR") and len(iban) ==26hesap = BankaHesabi("Ahmet Yılmaz", "TR123456789012345678901234")
hesap.para_yatir(10000)
hesap.faiz_uygula()
print(hesap) # BankaHesabi(Ahmet Yılmaz, 10300.00 TL)print(len(hesap)) # 2
NumPy, çok boyutlu diziler üzerinde yüksek performanslı matematiksel işlem yapma imkânı sunar. Pandas ise yapılandırılmış veri analizi için tablolar (DataFrame) üzerinde çalışır:
import numpy as np
import pandas as pd
# NumPy — vektörize işlemlerdizi = np.array([1, 2, 3, 4, 5], dtype=np.float64)
print(dizi *2) # [2. 4. 6. 8. 10.]print(np.sum(dizi)) # 15.0print(np.mean(dizi)) # 3.0print(np.std(dizi)) # 1.4142...# Matris işlemleriA = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
print(A @ B) # matris çarpımıprint(np.linalg.det(A)) # determinantprint(np.linalg.inv(A)) # ters matris# Random sayı üretimirng = np.random.default_rng(seed=42)
normal_dagilim = rng.normal(loc=0, scale=1, size=(1000,))
print(f"Ortalama: {normal_dagilim.mean():.4f}")
print(f"Std: {normal_dagilim.std():.4f}")
# Pandas — veri analizinp.random.seed(42)
n =1000df = pd.DataFrame({
"yas": rng.integers(18, 65, n),
"maas": rng.normal(15000, 5000, n).round(2),
"departman": rng.choice(["Yazılım", "Pazarlama", "Finans", "İK"], n),
"performans": rng.choice(["Düşük", "Orta", "Yüksek"], n, p=[0.2, 0.5, 0.3])
})
# Temel istatistiklerprint(df.describe())
# Gruplama ve agregasyonozet = df.groupby("departman").agg(
ortalama_maas=("maas", "mean"),
medyan_yas=("yas", "median"),
calisan_sayisi=("maas", "count")
).round(2)
print(ozet.sort_values("ortalama_maas", ascending=False))
# Filtreleme ve sorguyuksek_maasli = df.query("maas > 20000 and performans == 'Yüksek'")
print(f"Yüksek maaşlı, yüksek performanslı: {len(yuksek_maasli)}")
# pivot tablepivot = df.pivot_table(
values="maas",
index="departman",
columns="performans",
aggfunc="mean").round(0)
print(pivot)
Web Geliştirme — FastAPI
Flask ve Django popüler çerçeveler olmakla birlikte FastAPI, modern Python tiplemesini ve otomatik API dokümantasyonunu birleştiren bir çerçeve olarak güçlü bir alternatif:
# pip install fastapi uvicorn pydanticfrom fastapi import FastAPI, HTTPException, Depends
from pydantic import BaseModel, EmailStr, Field
from typing import Optional
import uvicorn
app = FastAPI(title="Kullanıcı API", version="1.0.0")
# Pydantic model — veri doğrulamaclassKullaniciOlustur(BaseModel):
ad: str = Field(..., min_length=2, max_length=50)
email: str = Field(..., pattern=r"^[^@]+@[^@]+\.[^@]+$")
yas: Optional[int] = Field(None, ge=18, le=120)
classKullaniciYanit(BaseModel):
id: int
ad: str
email: str
# Basit in-memory veritabanıkullanicilar_db: dict[int, dict] = {}
sayac =0@app.get("/")
asyncdefkok():
return {"mesaj": "API çalışıyor", "versiyon": "1.0.0"}
@app.post("/kullanicilar", response_model=KullaniciYanit, status_code=201)
asyncdefkullanici_olustur(kullanici: KullaniciOlustur):
global sayac
sayac +=1 yeni = {"id": sayac, **kullanici.model_dump()}
kullanicilar_db[sayac] = yeni
return yeni
@app.get("/kullanicilar/{kullanici_id}", response_model=KullaniciYanit)
asyncdefkullanici_getir(kullanici_id: int):
if kullanici_id notin kullanicilar_db:
raise HTTPException(status_code=404, detail="Kullanıcı bulunamadı")
return kullanicilar_db[kullanici_id]
@app.get("/kullanicilar", response_model=list[KullaniciYanit])
asyncdefkullanici_listele(atla: int =0, limit: int =10):
liste = list(kullanicilar_db.values())
return liste[atla: atla + limit]
if __name__ =="__main__":
uvicorn.run(app, host="0.0.0.0", port=8000, reload=True)
Makine Öğrenmesi — Scikit-learn
# pip install scikit-learn pandas numpy matplotlibfrom sklearn.model_selection import train_test_split, cross_val_score, GridSearchCV
from sklearn.preprocessing import StandardScaler, LabelEncoder
from sklearn.pipeline import Pipeline
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report, confusion_matrix
import numpy as np
import pandas as pd
# Örnek veri seti oluşturrng = np.random.default_rng(42)
n =500X = pd.DataFrame({
"yas": rng.integers(18, 65, n),
"maas": rng.normal(15000, 5000, n),
"deneyim": rng.integers(0, 30, n),
"egitim": rng.integers(1, 5, n)
})
y = (X["maas"] >18000).astype(int) # yüksek maaş sınıfı# Eğitim/test bölümüX_egitim, X_test, y_egitim, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
# Pipeline — ön işleme + modelboru_hatti = Pipeline([
("olcekleme", StandardScaler()),
("siniflandirici", RandomForestClassifier(n_estimators=100, random_state=42))
])
boru_hatti.fit(X_egitim, y_egitim)
# Değerlendirmey_tahmin = boru_hatti.predict(X_test)
print(classification_report(y_test, y_tahmin, target_names=["Düşük", "Yüksek"]))
# Çapraz doğrulamacv_skorlari = cross_val_score(boru_hatti, X, y, cv=5, scoring="f1")
print(f"CV F1 skoru: {cv_skorlari.mean():.3f} ± {cv_skorlari.std():.3f}")
# Hiperparametre optimizasyonuparam_izgarasi = {
"siniflandirici__n_estimators": [50, 100, 200],
"siniflandirici__max_depth": [None, 5, 10],
"siniflandirici__min_samples_split": [2, 5]
}
izgara_arama = GridSearchCV(
boru_hatti, param_izgarasi, cv=3, scoring="f1", n_jobs=-1)
izgara_arama.fit(X_egitim, y_egitim)
print("En iyi parametreler:", izgara_arama.best_params_)
Otomasyon ve Web Scraping
# pip install requests beautifulsoup4 lxmlimport requests
from bs4 import BeautifulSoup
import time
from urllib.parse import urljoin, urlparse
classWebKaziyici:
def__init__(self, temel_url: str, bekleme: float =1.0):
self.temel_url = temel_url
self.bekleme = bekleme
self.oturum = requests.Session()
self.oturum.headers.update({
"User-Agent": "Mozilla/5.0 (Educational Scraper)" })
defsayfa_al(self, url: str) -> BeautifulSoup |None:
try:
yanit = self.oturum.get(url, timeout=10)
yanit.raise_for_status()
return BeautifulSoup(yanit.text, "lxml")
except requests.RequestException as hata:
print(f"Hata [{url}]: {hata}")
returnNonedefbasliklar_al(self, url: str) -> list[dict]:
soup = self.sayfa_al(url)
ifnot soup:
return []
sonuclar = []
for h in soup.find_all(["h1", "h2", "h3"]):
sonuclar.append({
"etiket": h.name,
"metin": h.get_text(strip=True)
})
time.sleep(self.bekleme) # sunucuya saygıreturn sonuclar
# Selenium ile dinamik içerik# pip install selenium webdriver-managerfrom selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
defdinamik_icerik_al(url: str) -> str:
secenekler = webdriver.ChromeOptions()
secenekler.add_argument("--headless")
secenekler.add_argument("--no-sandbox")
surucu = webdriver.Chrome(options=secenekler)
try:
surucu.get(url)
bekle = WebDriverWait(surucu, 10)
# Belirli bir elementin yüklenmesini bekle element = bekle.until(
EC.presence_of_element_located((By.ID, "icerik"))
)
return element.text
finally:
surucu.quit()
Asenkron Programlama
import asyncio
import aiohttp
import aiofiles
from typing import AsyncGenerator
asyncdefurl_indir(oturum: aiohttp.ClientSession, url: str) -> dict:
try:
asyncwith oturum.get(url, timeout=aiohttp.ClientTimeout(total=10)) as yanit:
icerik =await yanit.text()
return {"url": url, "durum": yanit.status, "boyut": len(icerik)}
exceptExceptionas hata:
return {"url": url, "hata": str(hata)}
asyncdefcoklu_indir(url_listesi: list[str]) -> list[dict]:
asyncwith aiohttp.ClientSession() as oturum:
gorevler = [url_indir(oturum, url) for url in url_listesi]
sonuclar =await asyncio.gather(*gorevler, return_exceptions=True)
return [s for s in sonuclar if isinstance(s, dict)]
# Async generatorasyncdefveri_akisi(n: int) -> AsyncGenerator[int, None]:
for i in range(n):
await asyncio.sleep(0.1) # I/O simülasyonuyield i *2asyncdefmain():
# Async generator tüketasyncfor deger in veri_akisi(5):
print(deger)
# Async context managerasyncwith aiofiles.open("async_log.txt", "w") as f:
await f.write("Async yazma başarılı\n")
asyncio.run(main())
Bölüm 8 — Üretim Ortamı ve İyi Pratikler
Tip Sistemi ve Statik Analiz
Python’un tip ipuçları sistemi, büyük kod tabanlarında hata yakalamayı kolaylaştırır. mypy ile statik analiz yapılabilir:
from typing import TypeVar, Generic, Callable, Any
from collections.abc import Sequence
T = TypeVar("T")
U = TypeVar("U")
# Generic sınıfclassYigin(Generic[T]):
def__init__(self) ->None:
self._veriler: list[T] = []
defit(self, deger: T) ->None:
self._veriler.append(deger)
defal(self) -> T:
ifnot self._veriler:
raiseIndexError("Yığın boş")
return self._veriler.pop()
def__len__(self) -> int:
return len(self._veriler)
def__bool__(self) -> bool:
return bool(self._veriler)
# Callable tipidefuygula(fonksiyon: Callable[[T], U], dizi: Sequence[T]) -> list[U]:
return [fonksiyon(eleman) for eleman in dizi]
# TypedDictfrom typing import TypedDict
classKullaniciDict(TypedDict):
id: int
ad: str
email: str
aktif: bool
# mypy kurulumu ve kullanımpip install mypy
mypy --strict main.py
# ruff — hızlı linter ve formatter (Rust ile yazılmış)pip install ruff
ruff check .
ruff format .
Test Yazımı
# pytest ile test# pip install pytest pytest-covimport pytest
from unittest.mock import patch, MagicMock
classTestBankaHesabi:
deftest_para_yatirma(self):
hesap = BankaHesabi("Test", "TR12345678901234567890123456")
hesap.para_yatir(1000)
assert hesap.bakiye ==1000.0deftest_negatif_para_yatirma_hata_verir(self):
hesap = BankaHesabi("Test", "TR12345678901234567890123456")
with pytest.raises(ValueError, match="pozitif"):
hesap.para_yatir(-100)
deftest_yetersiz_bakiye_hatasi(self):
hesap = BankaHesabi("Test", "TR12345678901234567890123456", 500)
with pytest.raises(ValueError, match="Yetersiz"):
hesap.para_cek(1000)
@pytest.mark.parametrize("miktar,beklenen", [
(100, 100.0),
(0.01, 0.01),
(1_000_000, 1_000_000.0)
])
deftest_cesitli_miktarlar(self, miktar: float, beklenen: float):
hesap = BankaHesabi("Test", "TR12345678901234567890123456")
hesap.para_yatir(miktar)
assert abs(hesap.bakiye - beklenen) <1e-9# Mock ile dış bağımlılık yönetimideftest_api_cagri_basarisiz_olunca_yeniden_dener():
with patch("requests.get") as mock_get:
mock_get.side_effect = [
ConnectionError("Bağlantı hatası"),
ConnectionError("Bağlantı hatası"),
MagicMock(status_code=200, json=lambda: {"veri": "ok"})
]
# 3. denemede başarılı olması beklenir# ...test kodu...
# Test çalıştırmapytest -v
pytest --cov=. --cov-report=html # kapsama raporu
Not 1: Python sürümü seçerken daima en güncel kararlı sürümü tercih edin. Python 2, 2020’de resmi destek sonunu tamamladı ve aktif kullanımdan kaldırılmalıdır.
Not 2:pip install ile kurulan paketleri her zaman sanal ortam içinde kullanın. Sistem Python’una doğrudan paket kurmak, bağımlılık çakışmalarına yol açar.
Not 3: Üretim kodunda print() yerine logging modülünü kullanın. Log seviyeleri (DEBUG, INFO, WARNING, ERROR, CRITICAL) ve dönen dosya handler’ları büyük uygulamalarda izlenebilirliği artırır.
Not 4: Tip ipuçları zorunlu değil ama ekip çalışmasında ve büyük kod tabanlarında son derece değerlidir. mypy --strict ile statik analiz, çalışma zamanı hatalarının önemli bir bölümünü önceden yakalar.
Not 5: Generator’lar ve lazy evaluation, büyük veri setleriyle çalışırken bellek tüketimini dramatik biçimde düşürür. Milyonlarca satırlık CSV dosyasını satır satır işlemek, tüm dosyayı belleğe yüklemekten çok daha verimlidir.