koddla

Yazılımcıları bilgi ile güçlendirir.

Python’da __init__.py ne işe yarar?

__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_methodsu 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:

  1. 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.

Bir yanıt yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Back to top