Python & Decorators

Decorator Nedir?

Bir fonksiyona, o fonksiyonu değiştirmeden yeni bir özellik eklemek ister misin? Decorator tam olarak bunu yapar.

Bir benzetme yapalım:
Diyelim ki bir kahve dükkanın var ve “sade kahve” hazırlıyorsun. Ama bazı müşteriler şekerli, bazıları sütlü, bazıları da köpüklü istiyor. Sen bu ekstra istekleri karşılamak için sade kahveyi değiştirmiyorsun, onun üstüne ekstra bir şeyler ekliyorsun. İşte decorator da bir fonksiyona, onu bozmadan ekstra davranışlar eklemeye yarar.

Python’da decorator, aslında başka bir fonksiyona sarmalanan fonksiyondur. Yani bir fonksiyon alır, onun üzerine bir “katman” ekler.

def selamla():
    print("Merhaba!")

def ozel_decorator(fonk):
    def wrapper():
        print("Fonksiyondan önceki işlem.")
        fonk()
        print("Fonksiyondan sonraki işlem.")
    return wrapper

yeni_fonksiyon = ozel_decorator(selamla)
yeni_fonksiyon()

Çıktı:

Fonksiyondan önceki işlem.
Merhaba!
Fonksiyondan sonraki işlem.

Decorator’ı @ Sembolü ile Kullanmak

Bir önceki örnekte fonksiyonu manuel olarak decorate ettik:

yeni_fonksiyon = ozel_decorator(selamla)

Ama Python bize daha temiz ve okunabilir bir yol sunuyor: @ sembolü. Bu sembol, bir fonksiyona decorator’ı etiket gibi iliştirmek için kullanılır.

Yani az önceki örneği şöyle sadeleştirebiliriz:

def ozel_decorator(fonk):
    def wrapper():
        print("Fonksiyondan önceki işlem.")
        fonk()
        print("Fonksiyondan sonraki işlem.")
    return wrapper

@ozel_decorator
def selamla():
    print("Merhaba!")

selamla()

Aynı çıktıyı verir, ama bu kez @ozel_decorator satırı sayesinde Python, selamla fonksiyonunu ozel_decorator(selamla) şeklinde çağırır. Biz çağırmasak bile o bunu bizim yerimize yapar.

Decorator Ne İşe Yarar?

Şimdiye kadar hep fonksiyonun önüne/arkasına bir şey ekledik. Ama bu sadece “giriş seviyesi” kullanım. Gerçek dünyada decorator’lar için bir örnek gösterelim:

Yetkilendirme: Kullanıcının admin olup olmadığını kontrol etmek isteyebilirsin.

def admin_kontrol(fonk):
    def wrapper():
        kullanici = "user"
        if kullanici != "admin":
            print("Erişim reddedildi.")
        else:
            return fonk()
    return wrapper

@admin_kontrol
def paneli_goster():
    print("Admin paneli gösteriliyor.")

paneli_goster()
# Çıktı:

Erişim reddedildi.

Sık Kullanımlara Örnek:

  • FastAPI, Flask gibi framework’ler @app.get(), @app.post() gibi decorator’lar ile route tanımlar.
  • Django’da @login_required gibi decorator’lar sayfa erişimini kontrol eder.
  • Pandas, @staticmethod ya da @property gibi yerleşik decorator’larla çalışır.

Parametre Alan Decorator Nasıl Yazılır?

Normal decorator, bir fonksiyonu alıp onu sarmalayan bir yapıydı.Ama bazen decorator’ı kullanırken ona da bilgi vermek isteriz. Örneğin:

def mesaj_ile(mesaj):
    def decorator(fonk):
        def wrapper():
            print(f"{mesaj} - Fonksiyon çalışmadan önce")
            fonk()
            print(f"{mesaj} - Fonksiyon çalıştıktan sonra")
        return wrapper
    return decorator

@mesaj_ile("INFO")
def merhaba_de():
    print("Merhaba dünya!")

merhaba_de()
INFO - Fonksiyon çalışmadan önce
Merhaba dünya!
INFO - Fonksiyon çalıştıktan sonra

Decorator’lar, Python’un fonksiyonel programlama özelliklerinden belki de en güçlü olanlarından biri. Hem kod okunabilirliğini artırmak hem de tekrarlayan işlemleri daha şık bir şekilde çözmek için decorator’ları etkili şekilde kullanmak büyük avantaj sağlar. Umarım bu yazı anlaşılır olmuştur. Merak ettiğiniz herhangi bir şey varsa sosyal medya üzerinden iletişime geçebilirsiniz!

Yorum gönder