• ing. dekoratör. bazen sadece boya ya da duvar kağıdı yapanlar için de kullanılan bir kelime.
  • bazi python kullanicilarinin arkaplanini ve mekanigini kavramakta sikinti cektikleri iddia edilen, ozellik mi desem bi eksiklikten oturu dogmus tweak desem, bilemedigim nanesi. az evvel linki anilan makalede sadece decorator degil, python'un temel ozellikleri de anlatilir decorator mevzusunun daha iyi izahi icin. koskoca sozlukte python basligi altinda decorator(ve dekorator) adini anmi$ * sadece 2 (yaziyla iki) yazar** olmasi da sabah aksam yatip kalkip "abi python cogzel" modunda gezen yazarlar hakkinda kaygilara kapilmama vesile olmustur.
  • python 3 çalışırken az önce okuduğum yapılar.

    kendi anladığımı buraya yazayım.
    pek açıklanmamış çünkü. üstadlar el atar belki bir ara.
    (eski üstadların muazzam entrylerini okuyamıyoruz sanırım artık pek...)

    yanlışım varsa düzeltiniz. pythonda parametre olarak bir fonksiyon alan ve bunu süzgeçten geçirip aynı fonksiyonun değerini return eden bir yapı.

    pozitif tam sayıların toplamını alan bir fonksyion yazdığımızı hayal edelim.

    def sum_pos(a, b):
    if type(a) != int or type(b) != int or a <=0 or b<=0:
    return "pozitif tam sayı gir dedik."
    return a+b

    print(sum_pos(1,2))

    şimdi bu kontrolü fonksiyonun ilk satırında gerçekleştirdik. ancak diyelim ki zaman zaman bazı farklı operasyonlarda da pozitif tam sayı kontrolüne sahip olmamız gerek.

    sık sık tekrarlanan bir işlem olduğu için dry felsefesine aykırı oluyor. (bkz: don't repeat yourself)

    böyle bir durumda biz bir filtre yazsak ve o filtreye giren fonksiyonun parametreleri test edilse böylece her ihtiyac duyduğumuzda fonksiyon içine sürekli if yazmaktan kurtulsak daha mantıklı olur.

    bunu da şu şekilde yapabiliriz.

    öncelikle fonksiyonu ve o fonksiyona girecek parametreleri alan ve bunları if clauselar ile test eden bir fonksiyon yazarız.

    def sum_pos_filter(func):
    def wrapper(a, b):
    if type(a) != int or type(b) != int or a <= 0 or b <= 0:
    return "pozitif tam sayı gir dedik."
    return func(a, b)
    return wrapper

    bu bir filtredir. fonksiyonu alır ve içindeki kapsayıcı fonksiyonda ise parametreleri alır.

    artık yukarıdakini bir decorator olarak pozitif tam sayı kontrolü ihtiyacı duyan tüm fonksiyonlarımızda kullanabiliriz. şu şekilde:

    @sum_pos_filter
    def sum_pos(a, b):
    return a+b

    print(sum_pos(-1,2))

    artık @sum_pos_filter ı her ihtiyaç duyan fonksiyonda kullanabiliriz.

    not: yazdığım decorator 2 parameter içindir. henuz *args için nasıl olacağını öğrenmedim. öğrendiğimde hatırlarsam burayı editleyeceğim.

    edit:

    *args tuple dönermiş bu yüzden

    def sum_pos_filter(func):
    def wrapper(*args):
    for i in args:
    if type(i) != int or i <= 0:
    return "pozitif tam sayı gir dedik."
    return func(*args)
    return wrapper

    şeklinde düzenlememiz yeterlidir.
  • pyhon'un kendi içinden gelen güzelliklerden bir tanesi için.
    (bkz: lru_cache)
  • python'ın ilginç bir özelliği.

    öncelikle belirteyim çok iddialı değilim. sadece derdimi anlatacak kadar biliyorum bu işleri. yukarıda gayet güzel açıklanmış sahipsiz tarafından `:(bkz: #69243778)`. hem onu tamamlayıcı hem de farklı bir bakış getirmek için bunu giriyorum.

    python'da indentation önemli olduğu için belirtmek adına '---' kullandım.

    bir tane fonksiyonunuz var. gereğinden fazla basit bir fonksiyon bu:

    def basit_fonksiyon():
    --- print( "ben bir basit fonksiyonum")
    --- return

    elinizde bu fonksiyon var ve buna bir şekilde bir şeyler eklemek istiyorsunuz. örneğin şöyle:

    def basit_fonksiyon():
    --- print("ben bir basit fonksiyonum")
    --- print(ama sen gittin ya ben biraz değerlendim.")

    bunu iki şekilde yapabilirsiniz: birincisi elinizdeki fonksiyona kütürt diye bir şey eklersiniz. yani yukarıdaki ikinci satır gibi bir şey eklersiniz ya da yepisyeni bir fonksiyon tanımlar eskini bir güzel kopyalayıp yapıştırır ve mutlu mesut hayatınıza devam edebilirsiniz. fakat bunu birden çok fonksiyon için yapmak istediğinizi düşünün (yani ikinci satırı ekleme konusunda önlenemez, karşı konulamaz bir istediğiniz var, hangi fonksiyonu görseniz bu ikinci satırı eklemek için yanıp tutuşuyorsunuz). bu durum özellikle logging ve timing için bir sorun olabilir. bu işlemler için sürekli aynı kodu ki bu tek satır olmaz çoğu zaman kopyalayıp yapıştırmak istemezsiniz. dahası, ileri zamanda eklenen kodu çıkartıp fonksiyonun orijinal halini de kullanmak isteyebilirsiniz.

    bunu yapmak için yararlanılan python özellikleri: bir fonksiyon (veya nesne) başka bir fonksiyona giriş olarak verilebilir. ayrıca bir fonksiyon başka bir fonksiyonu döndürebilir.
    bunun için önce gerekli atarı yapacak olan fonksiyonu tanımlayalım. bu fonksiyon input değeri olarak basit_fonksiyonun ilk versiyonunu alacak.

    def atarli_fonksiyon(basit_fonksiyon):
    --- def dekore_eden_fonksiyon():
    --- --- basit_fonksiyon()
    --- --- print("ama sen gittin ya ben biraz değerlendim.")
    --- return dekore_eden_fonksiyon

    giriş değerini aldı. içinde başka bir fonksiyon tanımladı. bu fonksiyon gerekli dekorasyonu yapacak olan fonksiyon, allama pullama bunun işi. artık orası size kalmış. bu fonksiyonun içinde ilk önce basit_fonksiyonu çağırıyoruz, daha sonra da gerekli atarı yapacak satırı ekliyoruz. fakat dekore edecek fonksiyon henüz bir yerde çağırılmadı. dıştaki fonksiyonun return’üne de diyoruz ki çağır bu fonksiyonu ondan ne dönerse yolla gitsin.

    @atarli_fonksiyon
    def basit_fonksiyon():
    --- print("ben bir basit fonksiyonum")

    sonra da yukarıdaki gibi @ işaretini kullanıp diyoruz ki bak kardeşim atarli_fonksiyon’u al bundan sonra tanımlayacağım fonksiyona dekore et. yani basit_fonksiyonu bir insan atarli_fonksiyonu ise kıyafet olarak düşünebilirsiniz. bu özellik sayesinde aynı insana farklı farklı kıyafetler giydirebiliyorsunuz.
    en son basit fonksiyonu çağıralım, bakalım nolmuş.

    basit_fonksiyon()

    bunun sonunda dönmesini istediğimiz atar şu şekilde:

    ben bir basit fonksiyonum
    ama sen gittin ya ben biraz değerlendim.

    isterseniz @'li kısmı silip fonksiyonun saf halini kullanabilirsiniz fakat bence bunun asıl amacı aynı işi bir den çok fonksiyon için yapacaksanız kullanmak. ayrıca django'da da çok yaygın olarak kullanılırmış fakat oralar daha gelemedim. gelince bunu güncellerim.

    bu yazıda hem şu dersteki ilgili bölümden udemy hem de şu video'dan youtube haddinden fazlaca yararlandım.
  • 'metotların üstünde bir metot vardır.' ilkesini uygulayan özel sözdizimi.
  • python'da, bir fonksiyonda başka fonksiyonların işlevlerini kullanmak istediğimizde işlevleri kullanılmak istenen fonksiyonlar decorator olarak yazılabilir. işlevlerini kullanmak istediğimiz fonksiyonlar, işlevlerin geçerli olacağı fonksiyonun tanımlanacağı satırdan bir önceki satıra, başına @ işareti gelecek şekilde birlikte yazılır.

    bir fonksiyona birden fazla decorator eklenebilir. çalışmaya başlayacak ilk decorator, fonksiyona en yakın olan decoratör olur.

    yani aşağıdaki ifadede önce decorator1'deki işlem yapılır, sonra decorator2'ye geçilir, en son da decorator3'ün işlemi yapılır.

    @decorator3
    @decorator2
    @decorator1
    def fonksiyon(arguman): return arguman

    decorator'ler argüman alarak da fonksiyonlara eklenebilirler.

    örneğin:

    def karakter_ekle(karakter):
    def inner(func):
    def wrapper(*args, **kwargs):
    return func(*args, **kwargs) + " " + karakter
    return wrapper
    return inner

    def karakteri_buyut(func):
    def wrapper(*args, **kwargs):
    return func(*args, **kwargs).upper()
    return wrapper

    @karakter_ekle(karakter="world")
    @karakteri_buyut
    def fonksiyon(parametre): return parametre

    print(fonksiyon("hello"))

    yukarıdaki kodlara göre, önce hello karakter dizisi karakter_buyut bezeyicisi ile büyütülür. daha sonra world karakter dizisini argüman olarak alan karakter_ekle bezeyicisi ile büyük harflerden oluşan hello yazısının yanına, bir adet boşluk ve küçük harflerle world yazısı getirilir.
  • flask kullanırken login_required modunda sıklıkla kullanılır.

    login_required diye bir decorator fonksiyonu yazarsınız ve bunun gerektigi her yerde app.route() dan sonra, fonksiyon tanımından once yazarsınız ve ekstra login kontrolü yapmanıza gerek kalmaz.

    https://flask.palletsprojects.com/…/viewdecorators/
hesabın var mı? giriş yap