__init__.py
olarak isimlendirilmiş dosyalar, içinde bulundukları klasörleri birer Python paketi klasörüne dönüştürürler. Aşağıdaki gibi bir klasör yapınız varsa;
mydir/spam/__init__.py
mydir/spam/module.py
ve mydir
path’inize kayıtlıysa, module.py içerisindeki kodu aşağıdaki gibi import edebilirsiniz:
import spam.module
yada
from spam import module
Eğer __init__.py
dosyasını kaldırırsanız, Python artık bu klasör içerisinde submodül aramayı bırakır. Yukarıdaki gibi bir kullanım da haliyle hata verir.
__init__.py
dosyaları genellikle boştur. Ancak paketin belirli kısımlarını daha uygun isimler ile dışa akatarmak için ya da uygun fonksiyonları tutmak için de kullanılabilir. Yukarıdaki örnekten devam edersek, init modülünün içeriğine aşağıdaki gibi ulaşılır:
import spam
__init__.py ile değişken tanımlama
Klasörleri paket olarak tanımlamanın ve __all__ değişkenini tanımlamanın dışında, __init__.py
aynı zamanda paket seviyesinde değişken tanımlamanızı da sağlar. Bu şekilde bir tanımlama paketin sürekli kullandığı bir değişkeni tanımlamak için yararlı olabilir – API-benzeri. Aynı zamanda, bu yaklaşım pitonik tasarım felsefesine de uygundur.
Örnekle __init__.py’de değişken kullanımı
Bir veritabanı projesinde sürekli kullandığımız bir örneğe bakalım. Çoğunlukla Session
isimli bir değişkeni veritabanı
na ulaşmak için kullandığımızı düşünelim. database paketinde bir kaç tane modülümüz bulunuyor:
database/
__init__.py
schema.py
insertions.py
queries.py
__init__.py
dosyasında ise aşağıdaki kod bulunuyor:
import os
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
engine = create_engine(os.environ['DATABASE_URL'])
Session = sessionmaker(bind=engine)
Session
‘ı burada tanımladığımız için aşağıdaki syntak ile yeni bir session başlatabiliriz. Bu kod paketin dışından da içinden de aynı şekilde çalıştırılmış olacak
from database import Session
session = Session()
Tabiki burada yaptığımız işimizi çok az kolaylaştırarn bir kod. Bunun alternatifi session_olustur.py isminde bir dosyayı paketin içine yazmak olabilirdi. O zaman da yeni bir session başlatmak için şöyle yapardık:
from database.create_session import Session
session = Session()
__init__.py nerede kullanılır?
Her ne kadar Python __init__.py
olmadan da çalışıyor olsa da, yine de pakete bu dosyayı eklemek faydalı olacaktır.
Yukarıda da belirtildiği gibi, eklendiği klasörü bir paket gibi tanıyacaktır – bu dosya boş olsa bile.
__init__.py
‘yi gerçekten kullanmak isteyeceğimiz bir durum:
Aşağıdaki gibi bir klasör yapımızın olduğunu düşünelim:
main_methods
|- methods.py
ve methods.py
şunu içersin:
def foo():
return 'foo'
foo()
fonksiyonunu kullanmak için aşağıdaki gibi yapabiliriz:
from main_methods.methods import foo # Çağrı: foo()
from main_methods import methods # Çağrı: methods.foo()
import main_methods.methods # Çağrı: main_methods.methods.foo()
Belki, methods.py
‘yi main_methods
içerisinde tutmak isteriz? (runtime/dependency problemleri olabilir?) Ancak, yine de sadece main_methods
u import etmek isteriz.
Bu durumda methods.py
adını __init__.py
olarak değiştirirsek foo()
çağrısını sadece main_methods
‘u import ederek yapabiliriz:
import main_methods
print(main_methods.foo()) # 'foo' yazdırır
Bu yaklaşım şu yüzden işe yarar: __init__.py
bu durumda bir paket gibi değerlendirilir.
Hatta, bazı Python paketleri bu yöntemi gerçekten uygular. Bunun için bir örnek JSON olabilir. import json
ile aslında __init__.py
‘yi json
paketinden çağırıyoruz. (JSON paket yapısı):
Source code:
Lib/json/__init__.py
Kısaca __init__.py
__init__.py
kullanmak için üç nedenimiz var:
- Kolaylık/elverişlilik sağlaması amacıyla: diğer kullanıcıların metotlarınıza ulaşmak için paket hiyerarşisini tam olarak bilmelerinen gerek yok:
paketiniz/
__init__.py
file1.py
file2.py
...
fileN.py
# __init__.py
from file1 import *
from file2 import *
...
from fileN import *
# file1.py
def add():
pass
böylece diğer kullanıcılar aşağıdaki gibi çağrı yapabilir.
from paketiniz import add
Bu durumda aşağıdaki kullanımda olduğunun aksine file1’in nerede olduğunu bilmesine gerek yoktur.
from paketiniz.file1 import add
2. Bir şeyleri başlatmak istiyorsanız; mesela bir log işlemi:
import logging.config
logging.config.dictConfig(Your_logging_config)
3. sürekli kullandığınız değişkenleri paket seviyesinde tanımlamak için.