Paketler
Önceki Modüller Sonraki
Paketler
Paketler "noktalı modül isimleri" kullanarak Python'un modül isim alanının düzenlenmesinde kullanılırlar. Örneğin modül adı A.B adı A olan bir paket içindeki B adlı alt modülü gösterir. Nasıl modüller farklı modül yazarlarını birbirlerinin kullandığı global değişkenleri dert etmekten kurtarıyorsa, paketler de NumPy ya da PyOpenGL gibi çok sayıda modül içeren paketlerin birbirlerinin modül isimlerinin çakışması tehlikesinden kurtarır.
Ses dosyaları ve ses verisi üzerinde işlem yapacak bir modül kolleksiyonu (bir "paket") geliştirmek istediğinizi düşünelim. Farklı biçemlerdeki ses dosyalarını (.wav, .aiff, .au gibi dosya uzantıları olan) birbirine dönüştürmek, seslere efektler uygulamak veya sesleri filtrelemek için pek çok modüle ihtiyacınız olacak. Paketinizin muhtemel dizin yapısı şöyle olabilir:
Sound/                          Paketin en üst seviyesi
      __init__.py               paketi ilk kullanıma hazırlama
      Formats/                  Farklı dosya biçemleri için alt paket
              __init__.py
              wavread.py
              wavwrite.py
              aiffread.py
              aiffwrite.py
              auread.py
              auwrite.py
              ...
      Effects/                  ses efektleri alt paketi
              __init__.py
              echo.py
              surround.py
              reverse.py
              ...
      Filters/                  filtre alt paketi
              __init__.py
              equalizer.py
              vocoder.py
              karaoke.py
              ...
__init__.py dosyaları Python'un bu dizinleri paket içeren dizinler olarak algılaması için gereklidirler. Bunlar aynı isimli dizinlerin modül arama yolunda bulunacak diğer geçerli modülleri istemdışı saklamasını engeller. __init__.py boş bir dosya olabileceği gibi paketi ilk çalışmaya hazırlayabilir ya da daha sonra açıklanacak olan __all__ değişkenine değer atıyor olabilir.
Paketin kullanıcısı paketten dilediği bir modülü yükleyebilir.
import Sound.Effects.echo
Bu Sound.Effects.echo modülünü yükler. Modüle tüm ismi ile atıfta bulunulmalı:
Sound.Effects.echo.echofilter(input, output, delay=0.7, atten=4)
Aynı modülü yüklemenin bir diğer yolu:
from Sound.Effects import echo
Bu da echo alt modülünü yükler; ancak bunu paket adı verilmeden erişilebilir kılar ve modül şu şekilde kullanılabilir:
echo.echofilter(input, output, delay=0.7, atten=4)
Bir diğer yol da istenen işlev ya da değişkeni doğrudan yüklemektir:
from Sound.Effects.echo import echofilter
Bu da echo modülünü yükler; ancak echofilter() işlevini doğrudan erişilebilir kılar:
echofilter(input, output, delay=0.7, atten=4)
from PAKET import İSİM kullanılırken İSİM bir alt modül, alt paket ya da paket içinde tanımlı bir işlev, sınıf veya değişken ifade eden herhangi bir isim olabilir. import deyimi önce ismin pakette tanımlı olup olmadığına bakar; tanımlı değil ise bunun bir modül olduğunu varsayar ve bunu yüklemeye teşebbüs eder. Modülü bulamaz ise ImportError istisnası oluşur.
import ÖĞE.ALTÖĞE.ALTALTÖĞE ifadesinde ise son ismin dışındaki isimler paket olmalıdır. Son isim bir modül veya paket olabilir; ancak bir önceki ismin içinde tanımlanan bir işlev ya da değişken olamaz.
Bir paketten * yüklemek
Kullanıcı from Sound.Effects import * yazdığında ne olur? Dosya sistemine ulaşılıp paketin içinde hangi alt paketlerin olduğunun bulunması ve hepsinin yüklenmesi beklenir. Ne yazık ki bu işlem küçük/büyük harf ayrımının olmadığı Windows ve Mac işletim sistemlerinde pek iyi çalışmaz. Bu işletim sistemlerinde ECHO.PY gibi bir dosyanın echo, Echo veya ECHO isimlerinden hangisi ile yüklenmesi gerektiğini belirlemenin garantili bir yolu yoktur. Örneğin, Windows 95 dosya adlarının ilk harfini daima büyük harf ile gösterir. DOS'un 8+3 harflik dosya adı uzunluğu kısıtlaması da uzun modül isimleri için sorun olmaktadır.
Tek çözüm paket yazarının açık bir paket indeksi hazırlamasıdır. Bir paketin __init__.py dosyası __all__ adlı bir liste tanımlıyorsa bu liste from PAKET import * ifadesi kullanıldığında yüklenecek modül isimlerinin listesi olarak kullanılır. Paketin yeni bir sürümü hazırlandığında bu listenin uygun şekilde güncellenmesi paket yazarının sorumluğundadır. Eğer paketten * yüklemeye ihtiyaç duyulmayacağına karar verilirse bu özellik kullanılmayabilir. Örneğin Sounds/Effects/__init__.py dosyasının içeriği şöyle olabilir:
__all__ = ["echo", "surround", "reverse"]
Bu from Sound.Effects import * ifadesinin Sound paketinden isimleri __all__ içinde geçen üç modülün yüklemesini sağlar.
__all__ tanımlanmamış ise from Sound.Effects import * ifadesi Sound.Effects paketindeki bütün alt modülleri yürürlükte olan isim alanına yüklemez; sadece Sound.Effects paketinin ve içindeki isimlerin yüklenmesini sağlar (muhtemelen __init__.py) dosyasını çalıştırdıktan sonra). Bundan önceki import deyimlerince yüklenen alt paketler de yüklenir. Şu koda bir bakalım:
import Sound.Effects.echo
import Sound.Effects.surround
from Sound.Effects import *
Bu örnekte echo ve surround modülleri from...import... ifadesi çalıştırıldığında Sound.Effects paketinde tanımlı oldukları için yürürlükte olan isim alanına yüklenirler. Bu __all__ tanımlı olduğunda da bu çalışır.
Genel olarak bir modül ya da paketten * yüklemek hoş karşılanmaz; çünkü çoğunlukla zor okunan koda neden olur. Bunun etkileşimli kipte kullanılmasının bir sakıncası yoktur. Ayrıca bazı modüller sadece belirli bir kalıba uyan isimleri verecek şekilde tasarlanmışlardır.
from PAKET import GEREKLİ_ALTMODÜL ifadesini kullanmanın hiç bir kötü tarafı yoktur. Yükleyen modül farklı paketlerden aynı isimli modüller yüklemeye gereksinim duymadığı sürece tavsiye edilen kullanım şekli de budur.
Birbirlerini Yükleyen Modüller
Alt modüller çoğu kez birbirlerine atıfta bulunurlar. Örneğin surround modülü echo modülüne ihtiyaç duyabilir. Aslında bu türden atıflar öyle yaygındır ki import deyimi standart modül arama yoluna bakmadan önce çağrıldığı paketin içinde arama yapar. Bu şekilde surround modülü import echo veya from echo import echofilter ifadeleri ile kolayca echo modülüne kavuşabilir. Yüklenmek istenen modül içinde bulunan pakette (yükleme yapmaya çalışan modülün bulunduğu paket) bulunamaz ise import deyimi aynı isimli üst seviyeli bir modül arar.
Paketler Sound paketindeki gibi alt paketler şeklinde düzenlenmişler ise farklı alt paketler içindeki modüllerin birbirilerine atıfta bulunmasının kısa bir yolu yoktur; paketin tam adı kullanılmalıdır. Örneğin, Sound.Filters.vocoder modülünün echo modülünü kullanması gerekiyor ise from Sound.Effects import echo ifadesi ile buna erişebilir.
Önceki Üst Ana Başlık Sonraki
dir() İşlevi Başlangıç Giriş ve Çıkış
Bir Linux Kitaplığı Sayfası