Modüller ve Kütüphaneler
Kodu dosyalara ayırmak, hazır ve dış kütüphaneleri kullanmak
← 06 · Sözlükler ve KümelerYol haritası08 · Dosya İşlemleri (hazırlanıyor)
Bölüm 7
- Hazır modüllerden gereken işlevleri
importile kullanmak - Bir işlevi ayrı
.pydosyasına taşıyıp başka bir programdan çağırmak - Doğrudan çalıştırma ile içe aktarma arasındaki farkı açıklamak
random,datetimeveosmodüllerini kullanıpdir()vehelp()ile yeni işlevleri keşfetmek- Birden fazla modülü paket içinde düzenleyip doğru yerden çalıştırmak
- PyPI’dan bir paket kurmak ve proje bağımlılığını kaydetmek
Bir İşlevi İki Programda Kullanmak
Geçen derste bir sözlükteki notlardan ortalama hesapladık. Şimdi aynı hesaba hem öğretmenin kullandığı programda hem de dönem sonu raporunda ihtiyaç duyduğumuzu düşünelim. İşlevi iki dosyaya kopyalarsak bir düzeltmeyi de iki yerde yapmamız gerekir.
Kodun Yeri
Ortalama hesabını tek bir dosyada tutup iki programdan kullanabiliriz. Bu dosya, diğer programların içe aktarabileceği bir modül olur.
not_hesabi.py # Ortak hesaplama işlevleri
ogretmen.py # not_hesabi.py dosyasını kullanır
donem_raporu.py # Aynı dosyayı kullanır
Burada amaç dosya sayısını artırmak değil, aynı davranışın tek yerde tanımlanmasını sağlamaktır.
Hazır Modüller
Python’ın standart kütüphanesi, sık kullanılan işler için modüller sağlar. math matematiksel işlemleri, statistics ise sayıların ortalama ve medyan gibi özetlerini hesaplar. Bunları kullanmak için ayrıca paket kurmamız gerekmez.
Modülü İçe Aktarma
import math ifadesi math adını programımıza ekler. Modüldeki işlevi çağırırken adını önde yazarız. math.ceil() yazımı, işlevin hangi modülden geldiğini gösterir.
ceil() sonucu üst tam sayıya yuvarlar. Üç araç yalnızca 24 kişiyi taşıyacağı için 26 kişiye dördüncü araç gerekir. Aynı modülde floor() aşağı yuvarlar. math.pi ise bir işlev değil sabittir; parantezsiz yazılır.
Bir Adı Doğrudan Alma
Yalnız ceil() kullanacaksak from math import ceil yazabiliriz. Bu kez işlevi math. öneki olmadan çağırırız. İki yazım aynı hesabı yapar; değişen, işlev adının programımızda nasıl göründüğüdür.
Ad Alanı
import math sonrasında math.ceil yazmamızın nedeni, ceil adının math modülünün ad alanında bulunmasıdır. from math import ceil ise ceil adını kullandığımız dosyanın ad alanına ekler.
import math
print(math.sqrt(81)) # 9.0
from math import sqrt
print(sqrt(81)) # 9.0Takma Ad
Bir modüle kısa ve anlaşılır bir ad verebiliriz. as modülün dosyasını değiştirmez; yalnızca bu programda kullanacağımız adı belirler.
Takma ad bir alışkanlık diye kullanılmamalı. math gibi kısa bir ad zaten açıksa olduğu gibi bırakmak daha okunaklıdır.
import math
→
mathceil · sqrt · pi
→
mathmodülün tamamı
from math import ceil
→
mathceil · sqrt · pi
→
ceilyalnız ceil
import statistics as stats
→
statisticsmean · median
→
statstakma ad
Üç biçim de modülü yükler. Değişen, dosyamızın ad alanına hangi adın eklendiğidir. Modül adını görünür tutmak, özellikle birden fazla modül kullandığımızda işlevin kaynağını izlemeyi kolaylaştırır.
Önceki Dersten Bir Örnek
Altıncı derste ürünleri döngüyle saymıştık. Standart kütüphanedeki Counter, aynı sayım işi için hazır bir araçtır. Önceki yöntemi anlamak önemlidir; hazır araç ne yaptığımızı bildiğimizde işimizi kısaltır.
Hangi İçe Aktarma Biçimi?
import math: Modül adını görünür tutarız vemath.ceil()yazarız.from math import ceil: Yalnız ihtiyaç duyduğumuz adı alır,ceil()yazarız.import statistics as stats: Modüle bu dosyada kullanacağımız başka bir ad veririz.
from math import * bütün uygun adları birden getirir. Hangi adın nereden geldiğini belirsizleştirebildiği için ders örneklerinde ve uygulama kodunda kullanmayacağız.
Kendi Modülümüz
Bir modül, Python tanımlarını ve ifadelerini içeren bir dosyadır. not_hesabi.py dosyasındaki ortalama() işlevini başka bir dosyadan içe aktaracağız. Bu bölümdeki çok dosyalı örnekleri bilgisayarınızda aynı klasöre kaydedip terminalden çalıştırın.
Ortak Hesaplama Dosyası
not_hesabi.py
def ortalama(notlar):
if not notlar:
return None
return sum(notlar.values()) / len(notlar)İşlev not sözlüğünü alır. Boş sözlükte bölme yapmaz; hesaplanacak not yoksa None döndürür.
Modülü Kullanan İlk Program
ogretmen.py dosyası, not_hesabi.py ile aynı klasördedir.
import not_hesabi
notlar = {101: 70, 102: 80, 103: 90}
sonuc = not_hesabi.ortalama(notlar)
if sonuc is not None:
print(f"Sınıf ortalaması: {sonuc:.1f}")Terminalde bu klasörden python ogretmen.py çalıştırdığımızda Sınıf ortalaması: 80.0 yazılır. Python modülü dosya adından bulur; import not_hesabi.py yazmayız. Boş bir sözlükte ortalama() None döndürür; None biçimlendirilemeyeceği için sonucu önce kontrol ediyoruz.
İkinci Program Aynı Modülü Kullanır
Dönem sonu raporunda da not ortalaması gerekiyor. donem_raporu.py dosyası modülden yalnız ortalama adını alır.
from not_hesabi import ortalama
donem_sonu_notlari = {101: 60, 102: 75}
print(ortalama(donem_sonu_notlari)) # 67.5Bu yazımda not_hesabi adı değil, ortalama adı programın ad alanına gelir. Birden fazla işlev çağırdığımızda not_hesabi.ortalama() gibi yazmak, işlevlerin hangi modülden geldiğini daha açık gösterir.
Dosyalar Arasındaki İlişki
proje/
├── ogretmen.py import not_hesabi
├── donem_raporu.py from not_hesabi import ortalama
└── not_hesabi.py def ortalama(...)
İki program aynı modülü içe aktarır. Hesaplamada bir düzeltme gerektiğinde yalnız not_hesabi.py dosyasını değiştiririz.
İçe Aktarma Sırasında Ne Olur?
Bir modülün dosya düzeyindeki ifadeleri ilk içe aktarmada çalışır. Bu küçük örnekte duyuru.py içindeki print() işlevi, biz başka bir işlev çağırmadan çıktı üretir.
duyuru.py
print("Duyuru modülü yüklendi")
def mesaj():
return "Sınav pazartesi"Aynı Modülü İki Kez İçe Aktarmak
main.py
import duyuru
import duyuru
print(duyuru.mesaj())Duyuru modülü yüklendi
Sınav pazartesi
Normal bir Python çalışmasında ikinci import, önceden yüklenen modülü yeniden kullanır. Dosyayı değiştirdikten sonra açık kalan bir Python oturumunda eski davranışı görürseniz oturumu yeniden başlatın.
import duyuru
Bellekte yok: dosya baştan sona çalışır
ÇıktıDuyuru modülü yüklendi
import duyuru
Bellekte var: hazır modül kullanılır
Çıktıyok
print(duyuru.mesaj())
Modüldeki işlev çağrılır
ÇıktıSınav pazartesi
Doğrudan Çalıştırma ve __name__
Python, çalıştırdığı ana dosyada __name__ değerini "__main__" yapar. Aynı dosya modül olarak içe aktarılırsa bu değer modülün adıdır. Bu farkı, yalnız doğrudan çalıştırırken yapılacak işlemleri ayırmak için kullanırız.
not_hesabi.py
def ortalama(notlar):
if not notlar:
return None
return sum(notlar.values()) / len(notlar)
if __name__ == "__main__":
ornek = {101: 70, 102: 90}
print(ortalama(ornek)) # 80.0Koruyucunun Etkisi
python not_hesabi.py
__name__ == "__main__"
80.0import not_hesabi
__name__ == "not_hesabi"
python not_hesabi.py komutu örnek hesabı çalıştırır. ogretmen.py içinden import not_hesabi yapıldığında ise örnek çıktı görünmez; yalnız tanımlar kullanıma hazır hâle gelir.
Modülün içinde her print() için bu koruyucu gerekmez. Önemli olan, dosya içe aktarılırken istemeden rapor üretmek, kullanıcıdan girdi istemek veya program akışını başlatmamaktır.
Python Modülü Nerede Arar?
Python, modül adını arama yolundaki konumlarda bulmaya çalışır. Çalıştırılan betiğin klasörü bu konumlar arasındadır; standart kütüphane ve kurulu paketler de arama yolunda yer alır. Arama yolu kullanılan Python ortamına göre değişebilir.
Bu proje için basitleştirilmiş arama yolu:
import not_hesabi
1Betiğin klasörünot_hesabi.py
2Standart kütüphanearanmaz
3Kurulu paketleraranmaz
Yerel modül yüklenir
import statistics
1Betiğin klasörüstatistics.py
2Standart kütüphanearanmaz
3Kurulu paketleraranmaz
Yerel dosya standart modülün yerini alır
import requests
1Betiğin klasörüyok
2Standart kütüphaneyok
3Kurulu paketleryok
ModuleNotFoundError
ogretmen.py ile not_hesabi.py aynı klasörde değilse önce dosya düzenini ve çalıştırma biçimini kontrol edin. ModuleNotFoundError, çoğu zaman yanlış yazılmış bir ad veya beklenmeyen proje yerleşimiyle ilgilidir.
Ad Çakışması
Kendi dosyamıza statistics.py adını verirsek import statistics yazdığımızda Python beklediğimiz standart kütüphane modülü yerine yerel dosyayı bulabilir. Modüllere amaçlarını anlatan özgül adlar verelim: not_hesabi.py, ogrenci_raporu.py gibi.
from ... import * kullanımından kaçınmak da aynı okunabilirlik kaygısıyla ilgilidir. Kodda bir adın hangi modülden geldiğini izleyebilmeliyiz.
Standart Kütüphaneden Örnekler
Kendi modülümüzü yazıp içe aktardık. Şimdi Python ile birlikte gelen başka modüllere bakalım: rastgele seçim, tarih ve çalışma ortamı gibi farklı ihtiyaçlarda hangi modüle başvuracağımızı göreceğiz.
ceil · sqrt · pirandint · choice · sampledate · now · strftimegetcwd · listdir · pathrandom: Sayı Üretme ve Seçim Yapma
random() sıfır dâhil, bir hariç aralıkta ondalık sayı üretir. Bir zar atışını randint(1, 6) ile simüle edebiliriz; bu kez iki sınır da olası sonuçlara dahildir. choice() bir diziden tek eleman seçer. shuffle() ise listeyi yerinde karıştırır ve None döndürür.
Sonuçlar her çalıştırmada değişebilir. choice() liste dışında string ve demet gibi dizilerde de çalışır: random.choice("abc"). Boş dizide eleman bulamaz; shuffle() ise değiştirilebilir bir dizi ister. Burada bir liste verdik.
random.seed(): Aynı Denemeyi Tekrarlamak
Bir algoritmayı denerken aynı rastgele sayı dizisini yeniden üretmek isteyebiliriz. Üreteci aynı başlangıç değeriyle iki kez başlatırsak, aynı çalışma içinde aynı sayı dizisini elde ederiz:
seed() sonucu daha rastgele yapmaz; deneyi tekrarlanabilir kılar. Örneklerde sık görülen 42 özel bir değer değildir, yalnızca yaygın bir gelenektir; başka bir sayı da seçebilirsiniz. Güvenlik amacıyla rastgele değer üretmek için random yerine secrets modülü gerekir.
datetime: Tarih ve Saat
date gün, ay ve yıl bilgisini; datetime bunlara ek olarak saati tutar. today() ve now() çalıştırıldığı andaki yerel zamanı okur, dolayısıyla çıktıları sabit değildir.
Bu çıktılarda saat ve tarih, kodu çalıştıran ortamın saatine bağlıdır. Gerçek bir son teslim zamanı saklayacaksak saat dilimini de ayrıca düşünmemiz gerekir; burada yalnız temel tarih ve saat kullanımını görüyoruz.
Tarihi İstenen Biçimde Yazmak
Bir raporun tarihini 05.11.2026 biçiminde göstermek istiyoruz. strftime() tarih nesnesinden bir string üretir. %d gün, %m ay, %Y dört basamaklı yıl anlamına gelir.
Saat için datetime.now().strftime("%H:%M") yazabiliriz. %H 24 saatlik düzende saati, %M dakikayı verir. Biçimlendirme tarih nesnesini değiştirmez.
os: Çalışma Klasörü
os.getcwd() geçerli çalışma klasörünü, os.listdir(".") bu klasördeki adları verir. os.chdir("veri") çalışma klasörünü değiştirir; bundan sonraki göreli yollar yeni klasöre göre yorumlanır.
import os
print(os.getcwd())
print(os.listdir("."))
os.chdir("veri") # Projede veri/ klasörü varsa
print(os.getcwd())Bu örneği kendi proje klasörünüzde deneyin. Tarayıcıdaki Python hücresi bilgisayarınızın klasörlerini değil, tarayıcıya ayrılmış dosya ortamını görür. chdir() bir modülün yerini değiştirmez; çalışan programın göreli dosya yollarını etkiler.
os.path: Yol ve Dosya Kontrolü
Proje kökünde veri/notlar.csv dosyası olduğunu varsayalım. join() yolun parçalarını işletim sistemine uygun ayraçla birleştirir. exists() yolun varlığını, isfile() dosya, isdir() klasör olup olmadığını sınar.
import os
yol = os.path.join("veri", "notlar.csv")
print(os.path.exists(yol))
print(os.path.isfile(yol))
print(os.path.isdir("veri"))
if os.path.isfile(yol):
print(os.path.getsize(yol)) # Bayt cinsinden boyutgetsize() var olmayan bir yolda hata verir. Önce isfile() kontrolü yapmamızın nedeni budur. Yolun gerçekten hangi klasöre göre çözüleceği, geçerli çalışma klasörüne bağlıdır.
os: Klasör ve Dosya İşlemleri
mkdir() tek bir klasör oluşturur; klasör zaten varsa hata verir. makedirs() iç içe klasörleri de oluşturabilir. rename() dosyayı yeniden adlandırabilir veya başka bir klasöre taşıyabilir. remove() dosyayı, rmdir() ise boş klasörü siler.
Deneme Klasöründe Taşıma ve Silme
Bu kodu yalnızca yerel bilgisayarınızda, ayrı bir ip7_deneme klasörünün içinden çalıştırın. Başlamadan önce klasöre deneme amaçlı boş bir taslak.txt dosyası koyun; ciktilar klasörü henüz bulunmasın:
ip7_deneme/
└── taslak.txt
Örnek önce dosyayı ciktilar içine taşır, ardından dosyayı ve boşalan klasörü siler.
Deneme Dosyasını Taşıyıp Silme
import os
os.makedirs("ciktilar", exist_ok=True)
os.rename("taslak.txt", os.path.join("ciktilar", "rapor.txt"))
os.remove(os.path.join("ciktilar", "rapor.txt"))
os.rmdir("ciktilar")exist_ok=True, ciktilar klasörü zaten varsa oluşturma hatasını önler. Ancak böyle bir klasörde önceden bulunan rapor.txt dosyası bu örnekte değiştirilebilir veya silinebilir. Bu yüzden kodu yalnız belirtilen boş deneme klasöründe çalıştırın. Silme işlemleri geri alınamayabilir. Dosya içeriğini okuma ve yazmayı sonraki derste ele alacağız.
Ortam Değişkenleri
Programın çalışma ayarları bazen ortam değişkenleriyle verilir. os.environ bunlara anahtar-değer yapısı gibi eriştirir; os.getenv(ad, varsayılan) ise aranan değişken yoksa verilen varsayılanı döndürür.
import os
print("DERS_MODU" in os.environ)
mod = os.getenv("DERS_MODU", "gelistirme")
print(mod)Ortam değişkenleri makineden makineye değişir. os.environ içeriğinin tamamını ekrana basmak doğru değildir; erişim anahtarları gibi gizli değerler de bulunabilir.
Modülleri Keşfetmek
Her modülün işlevlerini ezberlememiz beklenmez. Önce adları bulur, sonra kullanacağımız işlevin açıklamasına bakarız.
- İhtiyacı söyle"Listeden iki farklı öğrenci seçmek istiyorum"
- Adı bul
dir(random) - Belgeyi oku
help(random.sample) - Dene
random.sample(adlar, 2)
dir(): Modülde Hangi Adlar Var?
dir(modül) modülde tanımlı adların sıralı bir listesini verir. Listede işlevlerin yanı sıra sabitler ve __name__ gibi özel adlar da bulunabilir.
dir() bize adları gösterir; sqrt() işlevinin ne beklediğini veya ne döndürdüğünü açıklamaz. Bunun için belgeye bakmamız gerekir.
help(): İşlev Nasıl Kullanılır?
help() bir modülün ya da işlevin kullanım açıklamasını gösterir. Bir işlev seçtiğimizde parametreleri ve kısa açıklamayı okuyabiliriz:
import math
help(math.sqrt)Bu komutu yerel Python terminalinde deneyin. Çıktı terminale ve Python sürümüne göre farklı görünebilir. help(math) bütün modülü anlattığı için daha uzun bir belge açar; sorumuz tek bir işleve aitse help(math.sqrt) daha kullanışlıdır.
random.sample() İşlevini Bulmak
Örneğin bir listeden tekrar etmeyen iki öğrenci seçmek istiyoruz. dir(random) içinde sample adını bulup help(random.sample) ile parametrelerini inceledikten sonra şu çağrıyı yazabiliriz:
sample() iki farklı konumdan seçim yapar ve yeni bir liste döndürür; adlar değişmez. Hangi öğrencilerin seçileceği çalıştırmadan çalıştırmaya değişebilir.
Paketler
Proje büyüdükçe tek modüle birbiriyle ilgisiz işlevler yığmak zorlaşır. Paket, ilişkili modülleri bir dizin altında düzenler. İçe aktarırken dizin ve modül adlarını noktayla birleştiririz.
Bir Okul Paketi
proje/
├── main.py
└── okul/
├── __init__.py
├── notlar.py
└── ogrenciler.py
okul/notlar.py not hesaplarını, okul/ogrenciler.py öğrenci kayıtlarıyla ilgili işlevleri tutar. Başlangıç için __init__.py boş kalabilir. Bu dosyayla kurduğumuz yapı, sıradan bir Python paketidir.
İki Modülün İki Görevi
okul/notlar.py
def ortalama(notlar):
if not notlar:
return None
return sum(notlar.values()) / len(notlar)okul/ogrenciler.py
def kayit_ekle(ogrenciler, numara, ad):
if numara in ogrenciler:
return False
ogrenciler[numara] = ad
return TrueNot hesabı ile öğrenci kaydı farklı işlerdir. kayit_ekle() aynı numara zaten varsa mevcut kaydı değiştirmez; yeni bir öğrenci eklediğinde True döndürür.
Paketten İçe Aktarma
Proje kökündeki main.py iki modülden birer işlev alır:
from okul.notlar import ortalama
from okul.ogrenciler import kayit_ekle
ogrenciler = {101: "Ada", 102: "Deniz"}
kayit_ekle(ogrenciler, 103, "Ece")
notlar = {101: 70, 102: 80, 103: 90}
print(ogrenciler[103]) # Ece
print(ortalama(notlar)) # 80.0Bu örnekte okul paket, notlar ve ogrenciler modül, ortalama ile kayit_ekle ise modüllerdeki işlevlerdir. Komutu proje kökünden python main.py olarak çalıştırırız.
Paketten içe aktarmanın başka yazımları da vardır; bunları paket düzeni dersinde karşılaştıracağız.
__init__.py Ne İşe Yarar?
__init__.py, burada kullandığımız normal paketi açıkça tanımlar. Dosya boş olsa da from okul.notlar import ortalama çalışır. İleride paketin dışarıya sunduğu adları bu dosyada düzenleyebiliriz; ilk örnekte buna ihtiyacımız yok.
Python’da __init__.py olmadan da oluşturulabilen namespace package yapıları vardır. Bu dersin çok dosyalı örnekleri normal paket düzeniyle sınırlıdır.
Modül mü, Paket mi?
- Tek bir
.pydosyasında ilişkili işlevleri topluyorsak modül yeterlidir. - Birden fazla modül aynı konuya aitse onları bir paket altında düzenleyebiliriz.
- Standart kütüphane Python ile gelir; dışarıdan kurduğumuz kütüphaneler ayrı bir konudur.
importyazmak tek başına eksik bir dış paketi kurmaz.
Dosya sayısını baştan artırmamıza gerek yok. Bölme kararı, kodun yeniden kullanımına ve hangi parçaların birlikte değiştiğine dayanmalı.
Üçüncü Taraf Paketler
Bir sunucudaki kaydı okuyan küçük bir program yazmak istediğimizi düşünelim. Bunu standart kütüphaneyle de yapabiliriz; ancak HTTP istekleri için kullanılan requests paketi daha kısa ve okunaklı bir çözüm sunar. Böyle bir paketi kullanmadan önce projemizin Python ortamına kurmamız gerekir. PyPI, bu paketlerin yayımlandığı çevrimiçi dizindir. import requests satırı yalnızca kurulu bir paketi yükler; kurulumu kendisi yapmaz.
Bir Paketi Projeye Eklemek: uv
Birinci derste projeye özel ortam için uv kullanmıştık. Proje kökünde uv add requests komutu, requests bağımlılığını projeye ekler ve ortamı günceller. Ardından programı aynı ortamda uv run ile çalıştırırız.
uv add requests
uv run python api_oku.pyuv add, proje bağımlılığını pyproject.toml dosyasına yazar; çözümlenen sürümleri uv.lock dosyasında tutar. Projeyi başka bilgisayarda açan kişi uv sync ile aynı bağımlılıkları kurabilir. Bu komutları tarayıcıdaki kod hücresinde değil, proje klasöründe terminalden çalıştırın.
- PyPIPaketlerin yayımlandığı dizin
uv add requestsPaketi indirir- Proje ortamı
.venv/içine kurulur;pyproject.tomlveuv.lockgüncellenir import requestsProgram paketi kullanır
requests: İlk HTTP İsteği
requests standart kütüphanenin parçası değildir; önceki adımdaki uv add requests komutu tamamlanmış olmalıdır. Aşağıdaki kodu yerel api_oku.py dosyasına yazıp terminalde çalıştırın:
import requests
url = "https://jsonplaceholder.typicode.com/todos/1"
response = requests.get(url, timeout=5)
print(response.status_code)timeout=5, sunucu yanıt vermediğinde programın süresiz beklemesini önler. HTTP durum kodu isteğin sonucunu anlamamıza yardım eder; bağlantı veya sunucu sorunu varsa kod hata verebilir. Bu örnek internet erişimi gerektirir ve tarayıcıdaki Pyodide hücresi için hazırlanmadı.
JSON Yanıtını Kullanma
Sunucu başarılı bir yanıt verdiyse response.json() ile içeriği Python değerlerine dönüştürürüz. Bu adresteki yanıt bir sözlüktür; önceki derste öğrendiğimiz anahtarla erişimi burada kullanabiliriz.
import requests
url = "https://jsonplaceholder.typicode.com/todos/1"
response = requests.get(url, timeout=5)
response.raise_for_status()
kayit = response.json()
print(kayit["title"])
print(kayit["completed"])raise_for_status() başarısız HTTP durumunda hata üretir. json() çağrısı ise yanıtın gerçekten geçerli JSON içerdiğini varsayar; gerçek uygulamada ağ ve veri hatalarını ayrıca yönetiriz. Bu dersin amacı, dışarıdan kurduğumuz paketin programda nasıl kullanıldığını görmektir.
Bağımlılıkları Yeniden Kurmak
uv kullanan projede pyproject.toml hangi paketlerin gerektiğini, uv.lock ise seçilen kesin sürümleri kaydeder. Bu dosyaları projeyle paylaşırız; .venv/ klasörünü paylaşmayız. Yeni ortamda uv sync bağımlılıkları kurar.
Hangi paketin hangi sürümle gerektiğini kaydeder.
Her bilgisayar bunu uv sync ile yeniden kurar.
uv syncAlternatif: pip ile Kurulum ve Paket Bilgisi
pip de Python paket yöneticisidir. Aşağıdaki komutları etkinleştirilmiş bir sanal ortamda çalıştırın; böylece paketi sistemdeki başka bir Python kurulumuna yanlışlıkla yüklemezsiniz. python -m pip yazımı, pipi kullandığınız Python yorumlayıcısıyla çalıştırır.
python -m pip install requests
python -m pip list
python -m pip show requestslist kurulu paketleri, show requests seçilen paketin sürümü ve kurulu olduğu konum gibi bilgileri gösterir. Paket artık gerekmiyorsa python -m pip uninstall requests ile kaldırabiliriz. Bir projede uv akışını seçtiysek bağımlılık ekleme ve kaldırmayı uv add ile uv remove üzerinden sürdürmek daha tutarlıdır.
pip Projesinde Bağımlılık Dosyası
pip ile çalışan bir projede geleneksel yol, paketleri requirements.txt dosyasında listelemektir. pip freeze etkin ortamdaki kurulu paketlerin sürümlerini de yazdığı için komutu projeye özel, temiz bir sanal ortamda kullanmak gerekir:
python -m pip freeze > requirements.txt
python -m pip install -r requirements.txtBu iki iş akışı aynı sorunu çözer, fakat dosyaları aynı biçimde yönetmez. uv.lock dosyasını elle düzenlemeyiz; requirements.txt ise pip akışında kurulacak sürümleri satır satır belirtir.
requirements.txt İçeriği
Basit bir projede dosya elle de yazılabilir. Her satır bir bağımlılığı belirtir. Örneğin requests>=2,<3 ifadesi, sürüm 2 ve üzerini kabul ederken 3 ve üzerini dışarıda bırakır. requests==2.32.3 gibi == ise tam olarak o sürümü ister:
# requirements.txt
requests>=2,<3
python -m pip install -r requirements.txt bu dosyadaki koşullara uygun sürümleri kurar. pip freeze ise mevcut ortamda kurulu kesin sürümleri yazar. Biri kabul edilen sürüm aralığını, diğeri o ortamın o andaki kurulu hâlini ifade edebilir; dosyanın amacını bilerek seçmeliyiz.
Kullanımda Dikkat Edilecekler
Okunur İçe Aktarmalar
- İçe aktarmaları dosyanın başında tutmak, bağımlılıkları görmeyi kolaylaştırır.
- Kullanılan adın kaynağı belirsizleşiyorsa modül adını önde bırakın:
math.ceil()gibi. - Modül adını standart kütüphanedeki bir adla çakıştırmayın.
- İçe aktarılacak dosyanın üst düzeyinde yalnız gerekli tanımlar ve hafif başlangıç işleri bulundurun.
Aynı Dosyayı İki Şekilde Kullanmak
rapor.py dosyasını iki şekilde kullanabiliriz:
- Başka bir dosya
import raporyazar ve içindeki işlevleri kullanır. - Biz terminalde
python rapor.pyyazar ve dosyayı doğrudan çalıştırırız.
Dosyanın sonuna işlevi denemek için bir print() satırı yazdığımızı düşünelim. Doğrudan çalıştırınca bu satırın çalışmasını isteriz. Başka bir dosya yalnızca işlevleri almak için import yaptığında ise ekrana aniden deneme çıktısı gelmesini istemeyiz.
if __name__ == "__main__": satırı bu ayrımı yapar. Altındaki satırlar yalnızca dosya doğrudan çalıştırılınca çalışır.
ogretmen.py içinde: import rapor
80.0Bunu biz istemedikif altında
ogretmen.py içinde: import rapor
hiçbir şeyİşlev yine de kullanılabilirpython rapor.pyDosyayı doğrudan çalıştırınca __name__ değeri "__main__" olur. if doğru çıkar, deneme satırı çalışır ve 80.0 yazılır.
Bu if Ne Zaman Lazım?
- Dosyayı hem içe aktaracak hem doğrudan çalıştıracaksak.
- Deneme hesabı, ekrana rapor yazdırma, kullanıcıdan veri isteme gibi satırlar
ifaltına yazılır. - Dosyada yalnızca işlev tanımları varsa
ifgerekmez.
Çok dosyalı örnekler tarayıcıdaki tek kod hücresinde aynı biçimde çalışmaz. Bunları yerel proje dosyalarına yazıp terminalden deneyin; tek dosyalı standart kütüphane alıştırmaları ise sayfada çalıştırılabilir.
Alıştırmalar
Önce hangi modüle ihtiyaç olduğunu belirleyin. Çok dosyalı sorularda her dosyanın görevini ayrı düşünün ve komutu hangi klasörden çalıştırdığınızı belirtin.
Alıştırma 1: Servis Aracı Sayısı
Bir geziye 37 öğrenci katılıyor. Bir araçta en fazla 12 öğrenci taşınabiliyor. Standart kütüphaneden uygun işlevi içe aktararak gereken araç sayısını hesaplayın. Sonuç 4 olmalı.
Alıştırma 1 · Çözüm
Kesirli araç kullanamayız. Bölüm sonucu tam sayı değilse math.ceil() bir üst tam sayıyı verir.
Alıştırma 2: Uç Değere Bakmak
Bir sınavdaki notlar [50, 60, 70, 80, 100]. Standart kütüphanedeki statistics modülünü kullanarak ortalama ve medyanı yazdırın. Sonra 100 yerine 200 koyup iki ölçünün nasıl değiştiğini gözlemleyin.
Alıştırma 2 · Çözüm
Uç değer ortalamayı yükseltti; ortadaki değer olan medyan değişmedi. Burada amaç yalnız import yazmak değil, hazır işlevin ürettiği sonucu yorumlamaktır.
Alıştırma 3: Kendi Modülün
Bir öğrenci grubunun notlarını sözlükte tutuyorsunuz. not_hesabi.py dosyasına, eşik değere ulaşan öğrenci sayısını döndüren basarili_sayisi(notlar, esik=50) işlevini yazın. main.py dosyasında modülü içe aktarın ve sonucu yazdırın. Her iki dosya aynı klasörde olsun.
notlar = {101: 40, 102: 50, 103: 75}
beklenen sonuç: 2
Alıştırma 3 · Çözüm
not_hesabi.py
def basarili_sayisi(notlar, esik=50):
sayac = 0
for puan in notlar.values():
if puan >= esik:
sayac += 1
return sayacmain.py
import not_hesabi
notlar = {101: 40, 102: 50, 103: 75}
print(not_hesabi.basarili_sayisi(notlar)) # 250 sınır değeri sayılır. Hesaplama işlevi modülde kalır; main.py veriyi sağlar ve sonucu gösterir.
Alıştırma 4: Paket Yolunu Kur
Şu proje yapısında ozet() işlevi okul/rapor.py dosyasında tanımlı. main.py içinden işlevi içe aktarıp çağıran iki satırı yazın. okul/__init__.py boş olabilir.
proje/
├── main.py
└── okul/
├── __init__.py
└── rapor.py # def ozet(): ...
Alıştırma 4 · Çözüm
main.py
from okul.rapor import ozet
ozet()Komutu proje kökünden python main.py olarak çalıştırın. okul.rapor yolu, paketin ve modülün adını birlikte gösterir; .py uzantısı import ifadesinde yazılmaz.
Alıştırma 5: Tekrarlanabilir Kura
Dört öğrenciden iki kişiyi random.sample() ile seçin. Aynı seed değerini kullanarak seçimi bir kez daha yapın ve iki sonucun eşitliğini yazdırın. Kaynak öğrenci listesi değişmemeli.
Alıştırma 5 · Çözüm
Tohum değerini iki seçimden önce de ayarladığımız için sonuçlar eşittir. sample() yeni liste üretir; shuffle() kullansaydık adlar listesi değişirdi.
Alıştırma 6: Tarihli Rapor Yolu
Son teslim günü 5 Kasım 2026 olan bir raporun adını 2026-11-05.txt yapın. Dosyanın raporlar klasöründeki yolunu os.path.join() ile oluşturup yazdırın. Burada dosya oluşturmanız gerekmiyor.
Alıştırma 6 · Çözüm
isoformat() dosya adında kullanabileceğimiz 2026-11-05 metnini verir. Yol ayracını elle yazmadık; join() çalışılan işletim sistemine göre ekler.
Alıştırma 7: Çalışma Ortamını İncele
Yerel bilgisayarınızda küçük bir Python programı yazın. Geçerli çalışma klasörünü ve bu klasördeki yalnızca klasör adlarını yazdırın. DERS_MODU ortam değişkeni yoksa gelistirme değerini gösterin. Çıktı bilgisayarınıza göre değişecektir.
Alıştırma 7 · Çözüm
import os
print(os.getcwd())
for ad in os.listdir("."):
if os.path.isdir(ad):
print(ad)
print(os.getenv("DERS_MODU", "gelistirme"))Bu kod dosya adlarını filtreler, klasör adlarını bırakır. Program başka bir çalışma klasöründen başlatılırsa getcwd() ve listeleme sonucu değişir; bu nedenle sabit bir çıktı beklemiyoruz.
Alıştırma 8: Bilmediğin Bir İşlevi Bul
math modülünde factorial adlı işlev bulunup bulunmadığını dir() ile kontrol edin. Ardından yerel Python terminalinde help(math.factorial) açıklamasını okuyun ve 5! değerini hesaplayın.
Alıştırma 8 · Çözüm
import math
print("factorial" in dir(math)) # True
help(math.factorial)
print(math.factorial(5)) # 120dir() adı bulmamızı, help() işlevin ne yaptığını ve hangi argümanı beklediğini öğrenmemizi sağlar. Ardından işlevi kullanırız.
Alıştırma 9: Dışarıdan Paket Kullan
Projenize requests ekleyin. https://jsonplaceholder.typicode.com/todos/1 adresindeki JSON kaydını alıp title ve completed alanlarını yazdıran api_oku.py dosyasını oluşturun. uv kullanıyorsanız paket ve çalıştırma komutlarını da yazın. pip kullanıyorsanız bunu etkin bir sanal ortamda yapın.
Alıştırma 9 · Çözüm
uv projesinde terminal komutları:
uv add requests
uv run python api_oku.pyEtkin bir sanal ortamda pip kullanılıyorsa kurulum komutu python -m pip install requests olur. api_oku.py içeriği iki kurulum biçiminde de aynıdır:
import requests
response = requests.get(
"https://jsonplaceholder.typicode.com/todos/1", timeout=5
)
response.raise_for_status()
kayit = response.json()
print(kayit["title"])
print(kayit["completed"])Bu alıştırma internet bağlantısı ve yerel kurulum gerektirir. Bağlantı, HTTP durumu veya JSON içeriği beklenenden farklıysa kod hata verebilir; sonraki hata yönetimi bölümünde bu durumları ele alacağız.
Alıştırma 10: Koruyucuyu Yaz
not_hesabi.py dosyasında basarili_sayisi(notlar, esik=50) işlevi tanımlı. Dosyaya, yalnız doğrudan çalıştırıldığında {101: 40, 102: 75} notları için sonucu yazdıran bir örnek ekleyin. Sonra aynı klasörde yalnız import not_hesabi satırını içeren bir main.py yazın. İki komutu çalıştırıp çıktıları karşılaştırın.
python not_hesabi.py → 1
python main.py → (çıktı yok)
Alıştırma 10 · Çözüm
not_hesabi.py
def basarili_sayisi(notlar, esik=50):
sayac = 0
for puan in notlar.values():
if puan >= esik:
sayac += 1
return sayac
if __name__ == "__main__":
print(basarili_sayisi({101: 40, 102: 75})) # 1main.py
import not_hesabipython not_hesabi.py çalıştığında __name__ değeri "__main__" olur ve örnek yazdırılır. main.py modülü içe aktarırken __name__ değeri "not_hesabi" olduğu için koşul sağlanmaz; yalnız işlev tanımlanır.
Kendini Sına
Önce cevabı gerekçesiyle tahmin edin. Kod sorularında hangi adın hangi dosyanın ad alanında bulunduğunu özellikle kontrol edin.
Soru 1
import math
print(ceil(2.2))- A.
2 - B.
3 - C.
NameError - D.
ImportError - E.
None
Doğru: C. import math, ceil adını doğrudan eklemez. math.ceil(2.2) yazarsak sonuç 3 olur.
Soru 2
Bir öğrenci projesinde not hesapları, öğrenci kayıtları ve rapor işlevleri ayrı ayrı büyüyor. Hangi düzen bu kod için en uygundur?
- A. Hepsini tek büyük
.pydosyasında tutmak - B. Her işlevi ilgili programlara kopyalamak
- C. İlişkili işlevleri ayrı modüllere bölüp
okulgibi bir paket altında toplamak - D. Her modülden
from modul import *ile bütün adları almak - E.
__init__.pydosyasına bütün işlevleri yazıp modülleri silmek
Doğru: C. Aynı konuya ait modüller bir paket altında toplanır; her dosyanın görevi belli kalır. A büyüyen kodu okunmaz hâle getirir, B düzeltmeleri çoğaltır, D adların kaynağını belirsizleştirir.
Soru 3
duyuru.py dosyasının ilk satırı print("Yüklendi"). main.py aşağıdaki kodu içeriyor:
import duyuru
import duyuruNormal bir Python çalışmasında kaç kez Yüklendi yazılır?
- A. Hiç
- B. Bir kez
- C. İki kez
- D. Sonsuz kez
- E.
SyntaxErroroluşur
Doğru: B. Dosya düzeyindeki ifade ilk içe aktarmada çalışır. İkinci import, yüklenmiş modülü yeniden kullanır.
Soru 4
rapor.py içindeki aşağıdaki print() ne zaman çalışır?
if __name__ == "__main__":
print("Rapor hazır")- A. Yalnız
import raporsırasında - B. Dosya doğrudan çalıştırıldığında
- C. Her
importsırasında - D. Hiçbir zaman
- E. Yalnız paket içindeyken
Doğru: B. Dosya ana program olarak çalıştırıldığında __name__ değeri "__main__" olur. İçe aktarılırsa bu koşul sağlanmaz.
Soru 5
okul/notlar.py dosyasında ortalama() işlevi var. Proje kökündeki main.py için doğru içe aktarma hangisidir?
- A.
import okul/notlar.py - B.
from okul.notlar import ortalama - C.
from okul.py import notlar - D.
import ortalama from okul.notlar - E.
from okul/notlar import ortalama
Doğru: B. Paket ve modül adlarını noktayla ayırırız. İçe aktarma ifadesinde yol ayracı veya .py uzantısı kullanmayız.
Soru 6
random modülünde sample adlı işlevin bulunup bulunmadığını ve hangi argümanları aldığını araştırmak için hangi sıra uygundur?
- A. Önce
dir(random), sonrahelp(random.sample) - B. Önce
help(random), sonraimport sample - C. Önce
random.sample(), sonradir(sample) - D. Yalnız
print(random) - E. Yalnız
import random.sample
Doğru: A. dir() modüldeki adları listeler. Adı bulduktan sonra help() işlevin kullanım açıklamasını gösterir.
Soru 7
Yeni bir uv projesinde import requests satırı ModuleNotFoundError üretiyor. requests henüz proje bağımlılığı değil. İlk yapılacak işlem hangisi?
- A.
requests.pyadlı boş dosya açmak - B.
uv add requestsçalıştırmak - C. Yalnız
uv syncçalıştırmak - D.
from requests import *yazmak - E.
importsatırını iki kez çalıştırmak
Doğru: B. uv add requests paketi projeye ekler. uv sync, ancak bağımlılık zaten proje dosyasında kayıtlıysa onu kurabilir.
Kod Yazma: Modüle Ayırma
Aşağıdaki işlev hem main.py hem de deneme.py içinde kopya olarak bulunuyor. İşlevi not_hesabi.py dosyasına taşıyın. İki programda da işlevi aynı modülden çağıracak import satırını ve çağrıyı yazın. İşlevin davranışı değişmemeli.
def en_yuksek_not(notlar):
if not notlar:
return None
return max(notlar.values())not_hesabi.py
def en_yuksek_not(notlar):
if not notlar:
return None
return max(notlar.values())main.py ve deneme.py dosyaları aynı klasördeyse ikisinde de şu kullanım geçerlidir:
import not_hesabi
notlar = {101: 65, 102: 90}
print(not_hesabi.en_yuksek_not(notlar)) # 90Boş sözlük için None döndürme davranışı modüldeki işlevde korunur.
Özet ve Kazanımlar
Modüller: Kısa Özet
- Modül: Python tanımlarını ve ifadelerini içeren dosyadır.
import modulile alınır; adlarınamodul.islev()biçiminde erişilir. - İçe aktarma:
from modul import adyalnız belirtilen adı doğrudan kullanıma açar.asyerel bir takma ad verir. - Standart kütüphane:
math,statistics,collections,random,datetimeveosgibi modüller Python ile gelir. - Doğrudan çalıştırma:
if __name__ == "__main__":altındaki kod, dosya ana program olarak çalıştırıldığında yürür.
Paketler ve Kullanım İlkeleri
- Paket: İlişkili modülleri bir dizinde toplar.
okul.notlarifadesindeokulpaket,notlarmodüldür. - Yerleşim: Bu dersteki örnek paket boş bir
__init__.pydosyası kullanır. Programı proje kökünden çalıştırırız. - Okunabilirlik: Özgül dosya adları seçer,
import *kullanımından kaçınır, modülü içe aktarırken istenmeyen işler başlatmayız.
Keşif ve Dış Paketler
- Keşif:
dir(modül)mevcut adları gösterir;help(modül.işlev)kullanım açıklamasını açar. - Üçüncü taraf paket: PyPI’dan gelen
requestsgibi bir paket,importedilmeden önce proje ortamına kurulmalıdır. - Bağımlılık:
uv addprojeye bağımlılık ekleyippyproject.tomlveuv.lockdosyalarını günceller.pipakışında paketlerrequirements.txtile taşınabilir.
Ayrıntılar için Python Modüller öğreticisine, random, datetime ve os belgelerine bakabilirsiniz. Paket yönetimi için uv proje rehberi ve pip belgeleri; HTTP örneği için requests hızlı başlangıcı yararlıdır.
← 06 · Sözlükler ve KümelerYol haritası08 · Dosya İşlemleri (hazırlanıyor)