Menu
Playground'da Dene

Python if __name__ == '__main__': Ana Koruma Deyimi Anlatıldı

if __name__ == '__main__' gerçekte ne yapıyor, neden her ciddi Python script'i eninde sonunda bu kalıba büyüyor ve bir dosyayı hem script hem de modül olarak nasıl yapılandırırsın.

Python'daki En Tuhaf Satır — Esrarı Çözüldü

Neredeyse herhangi bir Python dosyasını aç; eninde sonunda en altında bunu görürsün:

if __name__ == "__main__":
    main()

Sihirli gibi görünen bir boilerplate. Aslında ne yaptığını bilince çok pratik bir özellik — ve Python "script"ler ile "kütüphaneler" arasına bir sınır çizmediği için var.

Durum: Bir Dosyayı Kullanmanın İki Yolu

Python'daki her .py dosyası iki farklı şekilde kullanılabilir:

  1. Script olarak — doğrudan python3 file.py ile çalıştırırsın.
  2. Modül olarak — başka bir dosya import file ile içe aktarır.

Dil, hangisini yazdığını beyan etmeni istemez. Herhangi bir dosya ikisini de yapıyor olabilir.

math_helpers.py adında bir dosya düşün:

# math_helpers.py
def mean(values):
    return sum(values) / len(values)

def median(values):
    s = sorted(values)
    mid = len(s) // 2
    if len(s) % 2 == 0:
        return (s[mid - 1] + s[mid]) / 2
    return s[mid]

# Geliştirirken hızlı bir deneme
numbers = [3, 1, 4, 1, 5, 9, 2, 6]
print("mean:", mean(numbers))
print("median:", median(numbers))

Bu dosyayı doğrudan çalıştırırsan test çıktısını yazdırır — güzel. Ama başka bir dosya import math_helpers yapsa, o print deyimleri içe aktarma sırasında çalışır. Modülü kullanan herkes senin geliştirme notlarını görür. Pek hoş değil.

__name__ Nedir

Her Python modülünün __name__ adında yerleşik bir değişkeni vardır. Python bunu otomatik ayarlar:

  • Dosya içe aktarıldığında, __name__, modülün içe aktarma adına ayarlanır — yukarıdaki örnekte "math_helpers".
  • Dosya doğrudan çalıştırıldığında, Python __name__'i özel "__main__" string'ine ayarlar.

Bu sana hangi modda olduğunu anlamanın bir yolunu verir. "Yalnızca script" kodunu bir kontrolle sar:

# math_helpers.py
def mean(values):
    return sum(values) / len(values)

def median(values):
    s = sorted(values)
    mid = len(s) // 2
    if len(s) % 2 == 0:
        return (s[mid - 1] + s[mid]) / 2
    return s[mid]

if __name__ == "__main__":
    numbers = [3, 1, 4, 1, 5, 9, 2, 6]
    print("mean:", mean(numbers))
    print("median:", median(numbers))

Artık python3 math_helpers.py test çıktısını yazdırır. Ama başka bir dosyadan import math_helpers yapmak bloğu tamamen atlar — fonksiyonlar kullanılabilir ve istenmeyen hiçbir şey çalışmaz.

Yaygın Tamamlayıcı: main() Fonksiyonu

Çoğu gerçek script, kendine ait bir main() fonksiyonu büyütür ve koruma bloğunu minik tutar:

# process_orders.py
import sys

def load_orders(path):
    with open(path) as f:
        return [line.strip() for line in f if line.strip()]

def process(orders):
    for order in orders:
        print(f"Processing {order}")

def main():
    if len(sys.argv) < 2:
        print("Usage: python3 process_orders.py <file>")
        sys.exit(1)
    orders = load_orders(sys.argv[1])
    process(orders)

if __name__ == "__main__":
    main()

Mantığı doğrudan if korumasının altına koymak yerine neden main() için uğraşasın?

  1. Test edilebilirlik. Modülü içe aktarıp testlerden main()'i (veya yardımcılarından herhangi birini) çağırabilirsin.
  2. Yerel değişkenler. main() içinde tanımlanan her şey yerel değişkendir, modül düzeyinde bir isim değil. Bu, kazara isim çakışmalarını önler ve modülün dışa açık yüzeyini temiz tutar.
  3. Okunabilirlik. Koruma bloğu artık iki satırdır — bir yığın mantık değil, net bir "script giriş noktası".

Hızlı Bir Gösterim

Davranışı doğrudan görebilirsin:

main.py
Output
Click Run to see the output here.

Yukarıdaki parçacığı Python ile çalıştırdığında __name__ is: __main__ ve "script olarak çalıştırılıyor" yazar. Başka bir dosya bunu içe aktarsaydı, aynı kontrol diğer dalı yazdırırdı.

Korumaya İhtiyacın Olmadığı Yerler

Pek çok Python dosyası hiç büyümez. Hiç kimsenin içe aktarmayacağı kısa script'ler bunsuz da gayet iyidir:

# one_off_rename.py
import os
for name in os.listdir("."):
    if name.endswith(".txt"):
        os.rename(name, name.lower())

Bu gayet yeterli. Bir kütüphane kurmuyorsun; kimse bunu içe aktarmayacak. Ama bir dosyada yeniden kullanılabilir mantık olduğu an — ve onun yanında yan etkili kod da tutmak istiyorsan — korumaya uzan.

Kurulu Paketler İçin Giriş Noktaları

Kodunu gerçek bir paket olarak yayınlamaya başladığında daha resmi bir mekanizma vardır: paket meta verindeki entry_points, bir komutu bir fonksiyona eşler. Paketini kuran kullanıcılar, fonksiyonu doğrudan çağıran bir shell komutu alır. Ama kendi makinendeki bir klasörden çalışan script'ler için __main__ koruması standart araçtır.

Bu Bölümü Toparlarken

Artık elinde şunlar var:

  • Mantığına isim vermek için fonksiyonlar.
  • Esnek çağrılar için *args/**kwargs.
  • Tek kullanımlık fonksiyonlar için lambda'lar.
  • Fonksiyonları sarmak ve belgelemek için decorator'lar ve tip ipuçları.
  • Kodu dosyalar ve projeler arasında bölmek için modüller, pip ve sanal ortamlar.
  • Script'lerin ve modüllerin bir arada yaşamasını sağlayan __main__ koruması.

Sırada: Sınıflar

Şimdiye kadar fonksiyonları çoğunlukla düz verilerle — dict'ler, list'ler, tuple'lar — eşleştirdin. Bir sonraki bölüm sınıfları tanıtıyor; Python'un veriyi ve davranışı bir araya getirme yolu ve self, __init__, kalıtım ve dataclass gibi kavramların yaşadığı yer.

Sıkça Sorulan Sorular

if __name__ == '__main__' ne yapar?

Altındaki bloğu yalnızca dosya doğrudan çalıştırıldığında çalıştırır (dosya bir modül olarak içe aktarıldığında değil). Bu sayede hem script olarak çalıştırılabilen hem de fonksiyonları ve sınıfları için içe aktarılabilen bir .py dosyası yazabilirsin — script eylemleri içe aktarma sırasında tetiklenmeden.

Python'un main fonksiyonuna ihtiyacı var mı?

Hayır. Python dosyaları otomatik olarak yukarıdan aşağıya çalışır. Ama bir dosyanın aynı zamanda içe aktarılabilir olmasını istediğin bir mantığı olduğu anda if __name__ == '__main__' koruması önem kazanır — ve script'in üst düzey işini bir main() fonksiyonunun içine koymak yaygın bir tamamlayıcı alışkanlıktır.

__name__ ile __main__ arasındaki fark nedir?

__name__, Python'un her modülde ayarladığı özel bir değişkendir. Dosya içe aktarıldıysa, __name__ modülün adıdır (örneğin 'util'). Dosya doğrudan çalıştırıldıysa, Python __name__'i '__main__' string'ine ayarlar. if kontrolü bu ikisini karşılaştırır.

Coddy ile kodlamayı öğren

BAŞLA