CodeBlanks Logo Icon CodeBlanks

functools.wraps

functools.wraps ile decorator metaverisini korursun.

Sarmalın kimliği kaybolur

Süsleyici, hedef fonksiyonu sarmalayınca __name__ ve __doc__ gibi bilgiler sarmala geçer. Yani hello.__name__ artık "hello" değil, "wrapper" olur. Bu durum hata ayıklamayı ve yardım çıktısını bozar.

Çözüm: @functools.wraps(target) süsleyicisi sarmalın başına yazılır. Hedefin adını, belgelerini ve diğer meta verilerini sarmala kopyalar. Böylece dışarıdan bakıldığında sarmal, hedef gibi görünür.

wraps ne kopyalar?

@functools.wraps(fn) yalnızca adı değil, __doc__, __module__, __qualname__ ve __dict__ gibi öznitelikleri de kopyalar. Böylece help(hello) çağrısı sarmalı değil, gerçek hello belgesini gösterir.

Ayrıca imza bilgisi de daha doğru görünür. Kütüphane yazarken bu ayrım önemlidir; kullanıcılar hangi fonksiyonu çağırdığını bilmelidir. Süsleyici yazarken wraps kullanmak iyi bir alışkanlıktır.

Uygulama wraps kullanan süsleyici

import functools ile başla. call adında süsleyici tanımla; def call(fn): imzasıyla. İçinde @functools.wraps(fn) satırını, altına def wrapper(*args, **kwargs): tanımını yaz. Sarmalın gövdesinde return fn(*args, **kwargs) olsun. return wrapper ile bitir. @call ile def hello(): süsle; gövdede "Selam!" dizeni return et. En son print(hello.__name__) çağrısı yapsın.

Başlangıç kodu

main.py
# call süsleyicisini ve hello fonksiyonunu yaz

Örnek çözüm

main.py
# call süsleyicisini ve hello fonksiyonunu yaz
import functools

def call(fn):
    @functools.wraps(fn)
    def wrapper(*args, **kwargs):
        return fn(*args, **kwargs)
    return wrapper

@call
def hello():
    return "Selam!"

print(hello.__name__)

Beklenen çıktı

hello

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 @functools.wraps neyin kaybolmasını önler?

  • Parametrelerin
  • Fonksiyonun döndürdüğü değerin
  • Fonksiyon adı ve belgesinin Doğru cevap
  • Hata fırlatılmasının

Açıklama: @functools.wraps, hedefin adı ve belgesinin sarmala geçmesini önler.

2 wraps satırını tamamla

Soru
def call(fn):
    @____(fn)
    def wrapper(*args, **kwargs):
        return fn(*args, **kwargs)
    return wrapper
Cevap
def call(fn):
    @functools.wraps(fn)
    def wrapper(*args, **kwargs):
        return fn(*args, **kwargs)
    return wrapper

Açıklama: functools.wraps sarmalın başına yazılır.

3 wraps ve meta veriyi eşleştir

Kavram Anlamı
__name__ Fonksiyon adı
__doc__ Belge dizisi
__module__ Tanımlandığı modül
@functools.wraps Meta veriyi kopyalar

Orta seviye bölümündeki tüm dersler