Python [5] : Python Modülleri ve Paketleri; Kod Organizasyonu ve Yeniden Kullanım
Python’da programlar büyüdükçe, tüm kodu tek bir dosyada tutmak yönetilemez hale gelir. Kodun okunabilirliği azalır, bakımı zorlaşır ve farklı projelerde aynı kod parçalarını tekrar tekrar yazma ihtiyacı doğar. İşte bu noktada Python’un güçlü organizasyon mekanizmaları olan modüller ve paketler devreye girer. Modüller ve paketler, Python kodunu mantıksal birimlere ayırmanın, yeniden kullanılabilir bileşenler oluşturmanın ve büyük projeleri yapılandırmanın temel yoludur. Bu yapılar sayesinde kodumuzu daha düzenli, anlaşılır ve sürdürülebilir hale getirebiliriz. Bu rehberde, modüllerin ve paketlerin ne olduğunu, nasıl oluşturulup kullanıldığını ve Python’un bu yapıları nasıl bulup çalıştırdığını (import, from...import mekanizmaları dahil) ayrıntılı bir şekilde inceleyeceğiz. Bölüm 1: Modül Nedir? En basit tanımıyla, bir modül, Python tanımlamalarını ve ifadelerini içeren bir .py uzantılı dosyadır. Bu dosya içinde fonksiyonlar, sınıflar ve değişkenler tanımlayabiliriz. Bu tanımlamaları başka Python programlarından (veya modüllerden) içeri aktararak (import ederek) kullanabiliriz. Neden Modül Kullanırız? Kod Yeniden Kullanılabilirliği (Reusability): Sık kullandığınız fonksiyonları veya sınıfları bir modülde toplayıp, ihtiyaç duyduğunuz her projede bu modülü import ederek tekrar tekrar yazmaktan kurtulursunuz. İsim Alanı (Namespace) Organizasyonu: Her modül kendi özel isim alanına sahiptir. Bu, farklı modüllerde aynı isimde fonksiyon veya değişkenlerin bulunsa bile çakışmasını önler. Bir modüldeki isme erişmek için genellikle modül_adı.isim sintaksını kullanırız, bu da hangi ismin nereden geldiğini netleştirir. Mantıksal Gruplama ve Okunabilirlik: İlişkili fonksiyonları, sınıfları ve değişkenleri tek bir modül altında toplamak, kodun mantıksal yapısını güçlendirir ve anlaşılmasını kolaylaştırır. Bakım Kolaylığı: Belirli bir işlevsellikle ilgili kod tek bir modülde toplandığı için, o işlevsellikte bir değişiklik veya hata düzeltmesi gerektiğinde sadece ilgili modül üzerinde çalışmak yeterli olur. Basit Bir Modül Oluşturma Bir modül oluşturmak son derece basittir. Python kodu içeren bir dosyayı .py uzantısıyla kaydetmeniz yeterlidir. Örneğin, matematiksel bazı yardımcı fonksiyonları içeren matematik_yardimcisi.py adında bir dosya oluşturalım: matematik_yardimcisi.py PI = 3.1415926535 def topla(a, b): """İki sayıyı toplar.""" return a + b def carp(a, b): """İki sayıyı çarpar.""" return a * b def faktoriyel(n): """Negatif olmayan bir tamsayının faktöriyelini hesaplar.""" if not isinstance(n, int) or n < 0: return "Hata: Pozitif tamsayı giriniz." if n == 0: return 1 else: sonuc = 1 for i in range(1, n + 1): sonuc *= i return sonuc print("matematik_yardimcisi modülü yüklendi!") # Modül import edildiğinde bu satır çalışır Artık matematik_yardimcisi.py dosyamız bir modül haline geldi. İçindeki PI değişkenini, topla, carp ve faktoriyel fonksiyonlarını başka Python dosyalarından kullanabiliriz. Bölüm 2: Modülleri İçeri Aktarma (Importing Modules) Bir modülün içindeki kodları (fonksiyonlar, sınıflar, değişkenler) kullanabilmek için onu mevcut programımıza dahil etmemiz gerekir. Bu işleme içeri aktarma (importing) denir ve Python’da bunun için temel olarak import ve from...import ifadeleri kullanılır. 2.1. import module_name İfadesi En yaygın kullanılan yöntemdir. Belirtilen modülün tamamını içeri aktarır ve modül için bir isim alanı oluşturur. Modül içindeki üyelere erişmek için modül_adı.üye_adı formatını kullanmamız gerekir. Örnek olarak, yukarıda oluşturduğumuz matematik_yardimcisi modülünü kullanan ana_program.py adında bir dosya oluşturalım (bu dosyanın matematik_yardimcisi.py ile aynı dizinde olduğunu varsayalım): ana_program.py import matematik_yardimcisi # Modülün tamamını içeri aktar Modül içindeki üyelere 'modul_adi.' ön eki ile erişim print(f"PI Değeri: {matematik_yardimcisi.PI}") sayi1 = 15 sayi2 = 7 toplam_sonuc = matematik_yardimcisi.topla(sayi1, sayi2) print(f"{sayi1} + {sayi2} = {toplam_sonuc}") faktoriyel_5 = matematik_yardimcisi.faktoriyel(5) print(f"5! = {faktoriyel_5}") print(topla(1, 2)) # Hata! 'topla' doğrudan erişilebilir değil print(PI) # Hata! 'PI' doğrudan erişilebilir değil Bu programı çalıştırdığımızda, Python önce matematik_yardimcisi modülünü bulur, çalıştırır (ve "matematik_yardimcisi modülü yüklendi!" mesajını basar), sonra ana_program.py içindeki kodlar çalışmaya devam eder. import ifadesi, modülün kodunu sadece ilk kez import edildiğinde çalıştırır. Aynı modül tekrar import edilirse, Python zaten yüklenmiş olduğunu fark eder ve kodu tekrar çalıştırmaz. Avantajları: İsim alanı çakışmalarını önler. Hangi fonksiyonun veya değişkenin hangi modülden geldiği nettir (modul_adi.isim). Kodun okunabilirliğini artırır. Dezavantajları: Modül üyelerine erişmek için sürekli modül adını yazmak gerekebilir, bu da bazen kodu uzatabilir. Modüllere
![Python [5] : Python Modülleri ve Paketleri; Kod Organizasyonu ve Yeniden Kullanım](https://media2.dev.to/dynamic/image/width%3D1000,height%3D500,fit%3Dcover,gravity%3Dauto,format%3Dauto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxg5qyhg4spqksfgf6g6m.png)
Python’da programlar büyüdükçe, tüm kodu tek bir dosyada tutmak yönetilemez hale gelir. Kodun okunabilirliği azalır, bakımı zorlaşır ve farklı projelerde aynı kod parçalarını tekrar tekrar yazma ihtiyacı doğar. İşte bu noktada Python’un güçlü organizasyon mekanizmaları olan modüller ve paketler devreye girer.
Modüller ve paketler, Python kodunu mantıksal birimlere ayırmanın, yeniden kullanılabilir bileşenler oluşturmanın ve büyük projeleri yapılandırmanın temel yoludur. Bu yapılar sayesinde kodumuzu daha düzenli, anlaşılır ve sürdürülebilir hale getirebiliriz. Bu rehberde, modüllerin ve paketlerin ne olduğunu, nasıl oluşturulup kullanıldığını ve Python’un bu yapıları nasıl bulup çalıştırdığını (import, from...import mekanizmaları dahil) ayrıntılı bir şekilde inceleyeceğiz.
Bölüm 1: Modül Nedir?
En basit tanımıyla, bir modül, Python tanımlamalarını ve ifadelerini içeren bir .py uzantılı dosyadır. Bu dosya içinde fonksiyonlar, sınıflar ve değişkenler tanımlayabiliriz. Bu tanımlamaları başka Python programlarından (veya modüllerden) içeri aktararak (import ederek) kullanabiliriz.
Neden Modül Kullanırız?
Kod Yeniden Kullanılabilirliği (Reusability): Sık kullandığınız fonksiyonları veya sınıfları bir modülde toplayıp, ihtiyaç duyduğunuz her projede bu modülü import ederek tekrar tekrar yazmaktan kurtulursunuz.
İsim Alanı (Namespace) Organizasyonu: Her modül kendi özel isim alanına sahiptir. Bu, farklı modüllerde aynı isimde fonksiyon veya değişkenlerin bulunsa bile çakışmasını önler. Bir modüldeki isme erişmek için genellikle modül_adı.isim sintaksını kullanırız, bu da hangi ismin nereden geldiğini netleştirir.
Mantıksal Gruplama ve Okunabilirlik: İlişkili fonksiyonları, sınıfları ve değişkenleri tek bir modül altında toplamak, kodun mantıksal yapısını güçlendirir ve anlaşılmasını kolaylaştırır.
Bakım Kolaylığı: Belirli bir işlevsellikle ilgili kod tek bir modülde toplandığı için, o işlevsellikte bir değişiklik veya hata düzeltmesi gerektiğinde sadece ilgili modül üzerinde çalışmak yeterli olur.
Basit Bir Modül Oluşturma
Bir modül oluşturmak son derece basittir. Python kodu içeren bir dosyayı .py uzantısıyla kaydetmeniz yeterlidir.
Örneğin, matematiksel bazı yardımcı fonksiyonları içeren matematik_yardimcisi.py adında bir dosya oluşturalım:
matematik_yardimcisi.py
PI = 3.1415926535
def topla(a, b):
"""İki sayıyı toplar."""
return a + b
def carp(a, b):
"""İki sayıyı çarpar."""
return a * b
def faktoriyel(n):
"""Negatif olmayan bir tamsayının faktöriyelini hesaplar."""
if not isinstance(n, int) or n < 0:
return "Hata: Pozitif tamsayı giriniz."
if n == 0:
return 1
else:
sonuc = 1
for i in range(1, n + 1):
sonuc *= i
return sonuc
print("matematik_yardimcisi modülü yüklendi!") # Modül import edildiğinde bu satır çalışır
Artık matematik_yardimcisi.py dosyamız bir modül haline geldi. İçindeki PI değişkenini, topla, carp ve faktoriyel fonksiyonlarını başka Python dosyalarından kullanabiliriz.
Bölüm 2: Modülleri İçeri Aktarma (Importing Modules)
Bir modülün içindeki kodları (fonksiyonlar, sınıflar, değişkenler) kullanabilmek için onu mevcut programımıza dahil etmemiz gerekir. Bu işleme içeri aktarma (importing) denir ve Python’da bunun için temel olarak import ve from...import ifadeleri kullanılır.
2.1. import module_name
İfadesi
En yaygın kullanılan yöntemdir. Belirtilen modülün tamamını içeri aktarır ve modül için bir isim alanı oluşturur. Modül içindeki üyelere erişmek için modül_adı.üye_adı formatını kullanmamız gerekir.
Örnek olarak, yukarıda oluşturduğumuz matematik_yardimcisi modülünü kullanan ana_program.py adında bir dosya oluşturalım (bu dosyanın matematik_yardimcisi.py ile aynı dizinde olduğunu varsayalım):
ana_program.py
import matematik_yardimcisi # Modülün tamamını içeri aktar
Modül içindeki üyelere 'modul_adi.' ön eki ile erişim
print(f"PI Değeri: {matematik_yardimcisi.PI}")
sayi1 = 15
sayi2 = 7
toplam_sonuc = matematik_yardimcisi.topla(sayi1, sayi2)
print(f"{sayi1} + {sayi2} = {toplam_sonuc}")
faktoriyel_5 = matematik_yardimcisi.faktoriyel(5)
print(f"5! = {faktoriyel_5}")
print(topla(1, 2)) # Hata! 'topla' doğrudan erişilebilir değil
print(PI) # Hata! 'PI' doğrudan erişilebilir değil
Bu programı çalıştırdığımızda, Python önce matematik_yardimcisi modülünü bulur, çalıştırır (ve "matematik_yardimcisi modülü yüklendi!" mesajını basar), sonra ana_program.py içindeki kodlar çalışmaya devam eder. import ifadesi, modülün kodunu sadece ilk kez import edildiğinde çalıştırır. Aynı modül tekrar import edilirse, Python zaten yüklenmiş olduğunu fark eder ve kodu tekrar çalıştırmaz.
Avantajları:
İsim alanı çakışmalarını önler. Hangi fonksiyonun veya değişkenin hangi modülden geldiği nettir (modul_adi.isim).
Kodun okunabilirliğini artırır.
Dezavantajları:
Modül üyelerine erişmek için sürekli modül adını yazmak gerekebilir, bu da bazen kodu uzatabilir.
Modüllere Takma Ad Verme (as
Anahtar Kelimesi)
Modül isimleri uzun veya başka bir isimle çakışma potansiyeli taşıyorsa, import sırasında as anahtar kelimesi ile ona daha kısa veya farklı bir takma ad (alias) verebiliriz.
ana_program_alias.py
import matematik_yardimcisi as my # Takma ad 'my' olarak belirlendi
print(f"PI Değeri: {my.PI}") # Takma ad ile erişim
print(f"6! = {my.faktoriyel(6)}")
print(f"10 * 4 = {my.carp(10, 4)}")
matematik_yardimcisi.PI # Bu artık çalışmaz, çünkü takma ad kullandık
Bu, özellikle NumPy (import numpy as np), Pandas (import pandas as pd) gibi popüler kütüphanelerde yaygın olarak kullanılan bir yöntemdir.
2.2. from module_name import name1, name2, …
İfadesi
Bu ifade, bir modülden sadece belirli isimleri (fonksiyon, sınıf, değişken) doğrudan mevcut programın isim alanına aktarır. Bu sayede, aktarılan isimlere modül adını kullanmadan doğrudan erişebiliriz.
ana_program_from.py
from matematik_yardimcisi import PI, topla, faktoriyel # Sadece belirtilenleri aktar
Aktarılan isimlere doğrudan erişim
print(f"PI Değeri: {PI}")
sonuc = topla(25, 18)
print(f"25 + 18 = {sonuc}")
print(f"4! = {faktoriyel(4)}")
carp fonksiyonu import edilmediği için doğrudan erişilemez:
print(carp(5, 5)) # Hata! NameError: name 'carp' is not defined
Modül adı ile de erişilemez, çünkü modülün kendisi import edilmedi:
print(matematik_yardimcisi.carp(5, 5)) # Hata! NameError: name 'matematik_yardimcisi' is not defined
Avantajları:
Sık kullanılan isimlere erişimi kısaltır (modül adı ön ekine gerek kalmaz).
Dezavantajları:
Mevcut isim alanındaki başka bir isimle çakışma riski vardır. Eğer import ettiğiniz isim (örn: PI), programınızda zaten var olan başka bir PI değişkeni ile aynıysa, son tanımlanan diğerini ezer.
Hangi ismin nereden (hangi modülden) geldiğini takip etmek zorlaşabilir, bu da okunabilirliği azaltabilir.
İsimlere Takma Ad Verme (from … import … as …
)
from...import kullanırken de isim çakışmalarını önlemek veya isimleri kısaltmak için as ile takma ad verebiliriz.
ana_program_from_alias.py
from matematik_yardimcisi import faktoriyel as fact, PI as pi_degeri
print(f"7! = {fact(7)}")
print(f"PI = {pi_degeri}")
print(faktoriyel(3)) # Hata! Orijinal isim artık geçerli değil
print(PI) # Hata! Orijinal isim artık geçerli değil
2.3. from module_name import *
İfadesi (Kaçınılması Önerilir)
Bu ifade, bir modül içindeki (genellikle alt çizgi _ ile başlamayan) tüm isimleri mevcut isim alanına aktarır.
ana_program_import_star.py (Genellikle Kötü Fikir!)
from matematik_yardimcisi import *
Tüm isimler (PI, topla, carp, faktoriyel) doğrudan erişilebilir
print(PI)
print(topla(1,1))
print(carp(2,2))
print(faktoriyel(3))
Neden import *
Kötü Bir Fikirdir?
İsim Alanı Kirliliği (Namespace Pollution): Modüldeki tüm isimleri mevcut alana döker. Hangi isimlerin nereden geldiği belli olmaz ve mevcut isimlerle çakışma riski çok yüksektir. Bu, hataları ayıklamayı son derece zorlaştırır.
Okunabilirlik Kaybı: Kodu okuyan biri, kullanılan bir fonksiyonun veya değişkenin o modülden mi geldiğini yoksa yerel olarak mı tanımlandığını anlayamaz.
Gizli Bağımlılıklar: Modül güncellenip yeni isimler eklendiğinde veya mevcut isimler çıkarıldığında, kodunuz beklenmedik şekilde bozulabilir veya farklı çalışabilir.
import * kullanımı genellikle sadece interaktif Python kabuğunda hızlı denemeler yaparken veya çok özel ve kontrollü durumlarda kabul edilebilir. Gerçek projelerde kesinlikle kaçınılmalıdır.
(Not: Modül yazarları, all adlı özel bir liste tanımlayarak import * ile hangi isimlerin aktarılacağını kontrol edebilirler, ancak bu yine de genel kullanımı teşvik etmez.)
Bölüm 3: Modül Arama Yolu (sys.path
)
Python, bir import ifadesiyle karşılaştığında, istenen modül dosyasını (.py) nerede arayacağını nasıl bilir? Bu işlemi modül arama yolunu takip ederek yapar. Python şu sırayla bakar:
Geçerli Çalışma Dizini (Current Working Directory): Import işlemini yapan script’in bulunduğu dizin.
PYTHONPATH
Ortam Değişkeni: İşletim sisteminde tanımlanmışsa, bu ortam değişkeninde belirtilen dizinler listesi.
Kurulum Bağımlı Varsayılan Yollar: Python kurulumu sırasında belirlenen standart kütüphane dizinleri (genellikle Python kurulum dizini altındaki Lib ve Lib/site-packages gibi).
Bu arama yollarının tam listesi, Python’un sys modülü içindeki sys.path listesinde tutulur. Bu listeyi inceleyebilir ve hatta programatik olarak değiştirebilirsiniz (ancak genellikle değiştirilmesi önerilmez).
import sys
import pprint # Pretty print modülü, listeleri daha okunaklı yazdırmak için
print("Python Modül Arama Yolları (sys.path):")
pprint.pprint(sys.path)
Eğer Python istediğiniz modülü bu yolların hiçbirinde bulamazsa, ModuleNotFoundError hatası alırsınız.
Bölüm 4: if __name__ == “__main__”:
Bloğu
Python dosyaları hem doğrudan bir script olarak çalıştırılabilir hem de başka bir dosya tarafından modül olarak import edilebilir. Bazen bir dosyanın sadece doğrudan çalıştırıldığında belirli kodları yürütmesini, ancak modül olarak import edildiğinde bu kodları çalıştırmamasını isteyebiliriz (örneğin, test kodları veya örnek kullanım senaryoları).
Python, bir dosya çalıştırıldığında özel bir yerleşik değişken olan name'i ayarlar:
Eğer dosya doğrudan çalıştırılan ana program ise, name değişkeninin değeri "main" olur.
Eğer dosya başka bir modül tarafından import ediliyorsa, name değişkeninin değeri o modülün dosya adı (uzantısız) olur.
Bu davranışı kullanarak, bir kod bloğunun sadece dosya doğrudan çalıştırıldığında çalışmasını sağlamak için şu kalıbı kullanırız:
ornek_modul.py
def bir_fonksiyon():
print("bir_fonksiyon çalıştı.")
def baska_fonksiyon():
print("baska_fonksiyon çalıştı.")
print(f"ornek_modul içindeki name değeri: {name}")
Bu blok sadece dosya doğrudan çalıştırıldığında yürütülür.
if name == "main":
print("\nBu dosya doğrudan çalıştırıldı!")
print("Örnek kullanım veya test kodları burada çalıştırılabilir:")
bir_fonksiyon()
baska_fonksiyon()
print("Ana program bloğu bitti.")
--------------------------------------------------
baska_bir_dosya.py
import ornek_modul # ornek_modul'ü import et
print("\nbaska_bir_dosya çalışıyor...")
ornek_modul.bir_fonksiyon() # Modüldeki fonksiyonu kullan
baska_bir_dosya.py'yi çalıştırdığınızda çıktılar şöyle olacaktır:
ornek_modul içindeki name değeri: ornek_modul # Import edildiği için dosya adı
matematik_yardimcisi modülü yüklendi! # matematik_yardimcisi içindeki print (eğer oradaysa)
baska_bir_dosya çalışıyor...
bir_fonksiyon çalıştı.
ornek_modul.py'yi doğrudan çalıştırdığınızda ise çıktılar şöyle olacaktır:
ornek_modul içindeki name değeri: main # Doğrudan çalıştırıldığı için
matematik_yardimcisi modülü yüklendi! # matematik_yardimcisi içindeki print (eğer oradaysa)
Bu dosya doğrudan çalıştırıldı!
Örnek kullanım veya test kodları burada çalıştırılabilir:
bir_fonksiyon çalıştı.
baska_fonksiyon çalıştı.
Ana program bloğu bitti.
if name == "main": kalıbı, modüllerinizi hem kütüphane olarak kullanılabilir hem de kendi başlarına test edilebilir veya çalıştırılabilir hale getirmenin standart yoludur.
Bölüm 5: Paketler (Packages)
Projeniz büyüdükçe, tek bir modül bile yeterince organize olmayabilir. Çok sayıda modülünüz olduğunda, bunları daha da yapılandırmak için paketleri kullanırız.
Bir paket, temel olarak içinde özel bir dosya olan init.py dosyasını ve diğer modülleri (veya alt paketleri) içeren bir dizindir.
Neden Paket Kullanırız?
Hiyerarşik Yapı: Modülleri konu veya işlevselliğe göre dizinler altında gruplayarak projenin yapısını daha net hale getirir. Örneğin, bir web uygulamasında kullanıcı yönetimi modüllerini kullanicilar paketi altında, ürünlerle ilgili modülleri urunler paketi altında toplayabiliriz.
İsim Alanı Çakışmalarını Daha da Azaltma: Paket yapısı, paket_adı.modül_adı.isim gibi daha belirgin yollarla isimlere erişimi sağlayarak büyük projelerde isim çakışması olasılığını azaltır.
Büyük Kütüphanelerin Yönetimi: Python’un standart kütüphanesi ve NumPy, Django gibi büyük üçüncü parti kütüphaneler, kendi içlerinde paket yapısını yoğun olarak kullanırlar.
Paket Yapısı ve __init__.py
Basit bir paket yapısı şöyle görünebilir:
projem/
├── ana_script.py
└── benim_paketim/ # Bu bir paket dizini
├── init.py # Paketin Python tarafından tanınmasını sağlar
├── modul1.py
├── modul2.py
└── alt_paket/ # Bu bir alt paket dizini
├── init.py
└── modul_a.py
Burada:
benim_paketim ve alt_paket dizinleri pakettir çünkü içlerinde init.py dosyası bulunur.
init.py dosyası boş bile olsa, Python'a o dizinin bir paket olarak ele alınması gerektiğini söyler.
init.py dosyası aynı zamanda paket ilk import edildiğinde çalıştırılacak isteğe bağlı başlatma kodunu içerebilir veya paketten hangi isimlerin dışarıya daha kolay aktarılacağını kontrol etmek için kullanılabilir (örneğin, alt modüllerdeki önemli sınıfları doğrudan paket seviyesine getirmek gibi).
Örnek __init__.py
Kullanımı (İsimleri Yukarı Taşıma):
Diyelim ki modul1.py içinde Fonksiyon1 var ve biz bunu import benim_paketim yaptıktan sonra benim_paketim.Fonksiyon1 olarak kullanmak istiyoruz.
benim_paketim/init.py içine şunu ekleyebiliriz:
benim_paketim/init.py
print("benim_paketim paketi başlatılıyor...")
from .modul1 import Fonksiyon1 # '.' mevcut paketten import anlamına gelir
from .modul2 import DegiskenX
version = "1.0.0" # Paket versiyonu gibi bilgiler burada tanımlanabilir
Şimdi başka bir dosyadan:
import benim_paketim
benim_paketim.Fonksiyon1() # Doğrudan paket seviyesinde erişilebilir
print(benim_paketim.DegiskenX)
print(benim_paketim.version)
Paketlerden İçeri Aktarma
Paket içindeki modüllere veya üyelere erişmek için nokta (.) notasyonu kullanılır.
Mutlak İçe Aktarma (Absolute Imports)
İçe aktarma yolunu projenin kök dizininden (veya Python’un arama yolundaki bir dizinden) başlayarak tam olarak belirtir. Genellikle tercih edilen ve daha açık olan yöntemdir.
ana_script.py (projem dizininde)
Yöntem 1: Modülü import et
import benim_paketim.modul1
import benim_paketim.alt_paket.modul_a
benim_paketim.modul1.Fonksiyon1()
benim_paketim.alt_paket.modul_a.FonksiyonA()
Yöntem 2: Modülden belirli isimleri import et
from benim_paketim.modul2 import DegiskenX
from benim_paketim.alt_paket.modul_a import SinifA
print(DegiskenX)
nesne_a = SinifA()
Yöntem 3: init.py sayesinde yukarı taşınan isimleri import et
import benim_paketim
benim_paketim.Fonksiyon1() # init.py'de import edildiği için çalışır
Göreli İçe Aktarma (Relative Imports)
Aynı paket içindeki modüller arasında birbirlerini import etmek için kullanılır. Mevcut modülün konumuna göre yolu belirtmek için nokta (.) kullanılır.
from . import diger_modul: Aynı dizindeki (paketteki) diger_modul'ü import eder.
from .kardes_modul import isim: Aynı dizindeki kardes_modul'den isim'i import eder.
from .. import ust_paket_modulu: Bir üst dizindeki (paketteki) ust_paket_modulu'nü import eder.
from ..kuzen_paket import modul: Bir üst dizine çıkıp oradaki kuzen_paket'ten modul'ü import eder.
Örnek: benim_paketim/modul1.py içinden modul2.py'deki bir şeyi import etmek:
benim_paketim/modul1.py
from benim_paketim import modul2 # Mutlak import da çalışır
from . import modul2 # Göreli import - aynı paketteki modul2'yi bul
from .alt_paket import modul_a # Göreli import - alt paketteki modul_a'yı bul
def Fonksiyon1():
print("Fonksiyon1 çalıştı.")
print(f"Modul2'den DegiskenX: {modul2.DegiskenX}")
modul_a.FonksiyonA()
print(DegiskenX) # Hata! Doğrudan erişilemez
Ne Zaman Göreli Import Kullanmalı? Göreli importlar, paketinizin iç yapısını dış dünyadan bağımsız hale getirmek istediğinizde kullanışlıdır. Paketinizin adı değişse bile içindeki göreli importlar çalışmaya devam eder. Ancak, bazen kodun okunabilirliğini azaltabilirler ve sadece paket içindeki modüller arasında kullanılmalıdırlar. Ana script dosyalarından (paketin dışından) göreli import yapmaya çalışmak genellikle hataya yol açar (ImportError: attempted relative import with no known parent package).
Genel kural olarak, uygulamalarınızda mutlak importları tercih edin, sadece yeniden dağıtılabilir kütüphaneler/paketler yazarken paket içi referanslar için göreli importları değerlendirin.
Bölüm 6: Yerleşik (Built-in) Modüller ve Standart Kütüphane
Python, kurulumuyla birlikte gelen ve ek bir kurulum gerektirmeden doğrudan import edip kullanabileceğiniz çok sayıda yerleşik (built-in) modül içeren zengin bir Standart Kütüphane’ye sahiptir. Bu kütüphane, matematiksel işlemlerden dosya sistemi yönetimine, ağ iletişiminden veri işlemeye kadar birçok yaygın görev için hazır çözümler sunar.
Bazı yaygın standart kütüphane modülleri:
math: Matematiksel fonksiyonlar (sin, cos, sqrt, log, pi, e vb.).
random: Rastgele sayı üretimi ve seçimi.
os: İşletim sistemi ile etkileşim (dosya/dizin işlemleri, ortam değişkenleri vb.).
sys: Python yorumlayıcısı ile etkileşim (komut satırı argümanları, çıkış yapma, modül arama yolu vb.).
datetime: Tarih ve saat işlemleri.
json: JSON verilerini işleme (okuma/yazma).
re: Düzenli ifadeler (Regular Expressions) ile metin işleme.
collections: Özel konteyner veri tipleri (deque, Counter, defaultdict vb.).
urllib: URL'lerle çalışma ve HTTP istekleri yapma.
sqlite3: SQLite veritabanları ile çalışma.
Bu modülleri kullanmak için normal import veya from...import ifadelerini kullanırız:
import math
import random
from datetime import datetime
print(f"Pi sayısı: {math.pi}")
print(f"16'nın karekökü: {math.sqrt(16)}")
rastgele_sayi = random.randint(1, 100) # 1 ile 100 arasında rastgele tamsayı
print(f"Rastgele sayı: {rastgele_sayi}")
su_an = datetime.now()
print(f"Şu anki tarih ve saat: {su_an}")
print(f"Sadece yıl: {su_an.year}")
Standart kütüphaneyi etkin kullanmak, birçok yaygın problemi tekerleği yeniden icat etmeden çözmenizi sağlar.
Bölüm 7: Üçüncü Parti Paketler ve pip
Python’un gücü sadece standart kütüphanesiyle sınırlı değildir. Dünya çapında geliştiriciler tarafından oluşturulan ve Python Paket İndeksi (PyPI — Python Package Index) üzerinde yayınlanan on binlerce üçüncü parti paket bulunmaktadır.
Bu paketler, veri biliminden (NumPy, Pandas, Scikit-learn) web geliştirmeye (Django, Flask, Requests), görüntü işlemeden (Pillow, OpenCV) oyun geliştirmeye (Pygame) kadar akla gelebilecek her alanda özelleşmiş işlevsellikler sunar.
Bu üçüncü parti paketleri kullanmak için öncelikle onları sistemimize veya projemizin sanal ortamına (virtual environment) yüklememiz gerekir. Python’un standart paket yöneticisi olan pip bu iş için kullanılır. Komut satırına (terminal) genellikle şu şekilde komutlar yazılır:
Belirli bir paketi yüklemek için:
pip install paket_adi
Örnek: Requests kütüphanesini yükleme
pip install requests
Belirli bir versiyonu yüklemek için:
pip install paket_adi==versiyon_numarasi
Yüklü paketleri listelemek için:
pip list
Bir paketi kaldırmak için:
pip uninstall paket_adi
Paket yüklendikten sonra, standart kütüphane modülleri gibi import veya from...import kullanarak kodunuzda kullanabilirsiniz:
requests kütüphanesini kullanma (önce 'pip install requests' yapılmış olmalı)
import requests
try:
response = requests.get("https://api.github.com")
response.raise_for_status() # Hata varsa (4xx veya 5xx) istisna fırlatır
print("GitHub API'sine başarıyla bağlanıldı.")
# print(response.json()) # Dönen JSON verisini yazdırabiliriz
except requests.exceptions.RequestException as e:
print(f"Bağlantı hatası: {e}")
Sonuç
Modüller ve paketler, Python’da kod organizasyonunun temel direkleridir. Küçük script’lerden devasa uygulamalara kadar her ölçekteki projede kodun daha yönetilebilir, okunabilir, yeniden kullanılabilir ve sürdürülebilir olmasını sağlarlar. import ve from...import ifadeleri, bu modül ve paketlerdeki kodlara erişmemizi mümkün kılar.
Modüllerin nasıl oluşturulduğunu, farklı import yöntemlerinin artılarını ve eksilerini, Python’un modülleri nasıl bulduğunu (sys.path), if name == "main": kalıbının önemini ve paketlerle daha büyük projelerin nasıl yapılandırıldığını anlamak, etkili bir Python geliştiricisi olmak için kritik öneme sahiptir.
Standart kütüphanenin zenginliğinden ve pip aracılığıyla erişilebilen geniş üçüncü parti paket ekosisteminden yararlanarak, Python ile karmaşık problemleri daha verimli bir şekilde çözebilirsiniz. Kodunuzu mantıksal modüllere ve paketlere ayırma alışkanlığı kazanmak, uzun vadede size zaman kazandıracak ve daha kaliteli yazılımlar üretmenize yardımcı olacaktır.
Abdulkadir Güngör - Kişisel WebSite
Abdulkadir Güngör - Kişisel WebSite
Abdulkadir Güngör - Özgeçmiş
Github
Github
Linkedin