Parametreli decorator
- Python kursu
- İleri seviye
- Ders 1/83
- 5 dk
Parametreli decorator yazmayı öğrenirsin.
Parametreli decorator
Bir decorator, başka bir fonksiyonu saran ve davranışını değiştiren çağrılabilen bir nesnedir. Parametreli decorator ise, sarma işlemini yapılandıran ek argümanlar alır.
Önce dışta bir factory fonksiyonu tanımlanır: def repeat(n):. Bu fonksiyon, gerçek decorator'ü döndürür; decorator de sarmalanan fonksiyonu döndürür. Üç katmanlı yapı şöyledir:
def repeat(n):
def deco(fn):
def wrapper(*args):
for _ in range(n):
fn(*args)
return wrapper
return decoKullanımı @repeat(3) biçimindedir; çağrıdaki 3 argümanı factory'ye gider.
functools.wraps ile imza koruma
Bir decorator, sarmaladığı fonksiyonun adını, docstring'ini ve imzasını kaybeder; çünkü artık wrapper çağrılır. Bu durum hata ayıklamayı ve yardım çıktısını bozar.
Çözüm: functools.wraps(fn) decorator'ünü wrapper'ın üstüne koymak. Orijinal fonksiyonun meta verilerini wrapper'a kopyalar.
from functools import wraps
def repeat(n):
def deco(fn):
@wraps(fn)
def wrapper(*args):
...
return wrapper
return decoBöylece help(my_fn) hâlâ orijinal docstring'i gösterir.
Uygulama Parametreli @repeat decorator'ü yaz
Üç katmanlı bir parametreli decorator yaz. Factory repeat(n), decorator deco(fn) ve sarmalayan wrapper(*args) iç içe olsun. wrapper, fn(*args) çağrısını tam n kez yapsın. @wraps(fn) ile meta veriyi koru. @repeat(2) ile süslenmiş greet(name) fonksiyonu name değerini iki kez yazdırsın; en son greet("Ayşe") çağrısını yap.
Başlangıç kodu
from functools import wraps
# repeat(n) factory'si; içine deco ve wrapper tanımla
# wrapper'ı wraps decorator'ü ile süsle
# wrapper gövdesinde n kez orijinal fonksiyonu çağır
@repeat(2)
def greet(name):
print(name)
greet("Ayşe")Örnek çözüm
from functools import wraps
def repeat(n):
def deco(fn):
@wraps(fn)
def wrapper(*args):
for _ in range(n):
fn(*args)
return wrapper
return deco
@repeat(2)
def greet(name):
print(name)
greet("Ayşe")Beklenen çıktı
Ayşe Ayşe
Soru ve cevaplar
Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.
1 Parametreli decorator'de @repeat(3) çağrısındaki 3 nereye gider?
- Factory fonksiyonuna (repeat) Doğru cevap
- Doğrudan sarmalanan fonksiyona
- wrapper fonksiyonuna
- deco fonksiyonuna
Açıklama: repeat(3) önce factory'yi çağırır; 3 factory'nin n parametresine bağlanır.
2 wraps decorator'ünü ekle
from functools import wraps
def repeat(n):
def deco(fn):
@____(fn)
def wrapper(*args):
for _ in range(n):
fn(*args)
return wrapper
return deco
from functools import wraps
def repeat(n):
def deco(fn):
@wraps(fn)
def wrapper(*args):
for _ in range(n):
fn(*args)
return wrapper
return deco
Açıklama: @wraps(fn), orijinal fonksiyonun ad ve docstring'ini wrapper'a kopyalar.
3 Parametreli decorator katmanlarını eşleştir
| Kavram | Anlamı |
|---|---|
repeat(n) |
En dış factory |
deco(fn) |
Gerçek decorator |
wrapper(*args) |
Sarmalayan fonksiyon |
@wraps(fn) |
Meta veriyi korur |