ProgramlamaBackend Geliştirici

Python'da dekoratörlerin nasıl çalıştığını açıklayın. Ana faydaları nelerdir, nasıl uygulanır ve kullanımında hangi incelikler ortaya çıkabilir?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap

Dekoratörler — bir fonksiyonu alıp, onun davranışını genişleten veya değiştiren yeni bir fonksiyon döndüren fonksiyonlardır. Genellikle günlüğe kaydetme, yetki kontrolü, önbellekleme, çalışma süresi ve diğerleri için kullanılır.

Dekoratörler, kapanışlar (closure) veya __call__ yöntemini uygulayan sınıflar aracılığıyla gerçekleştirilir. Klasik sözdizimi:

# Basit dekoratör def simple_decorator(func): def wrapper(*args, **kwargs): print("Fonksiyondan önce") result = func(*args, **kwargs) print("Fonksiyondan sonra") return result return wrapper @simple_decorator def my_func(): print("Ana fonksiyon") my_func()

Sonuç şöyle çalışacaktır:

Fonksiyondan önce
Ana fonksiyon
Fonksiyondan sonra

Ana fayda — tekrarlayan mantığı ana iş mantığının dışında kapsüllemektir.

İncelikler:

  • functools.wraps kullanılmadığında, orijinal fonksiyonun adı ve docstring'i kaybolur.
  • Eğer dekoratör argüman alıyorsa, üçlü fonksiyon iç içe yazılır.

İkilem Sorusu

Soru: "Eğer bir fonksiyonu dekoratörle süslersem ve sonra __name__ ile fonksiyonun adını almayı denersem ne görürüm ve orijinal adı nasıl korurum?"

Cevap:

Varsayılan olarak adı sarmalayıcının adı (genellikle wrapper) olarak değişecektir. Orijinal meta verileri korumak için functools.wraps kullanın:

import functools def dec(f): @functools.wraps(f) def wrapper(*args): return f(*args) return wrapper @dec def foo(): pass print(foo.__name__) # 'foo' döndürür, 'wrapper' değil

Konuyla ilgili incelikleri bilmemekten kaynaklanan gerçek hata örnekleri


Hikaye

Büyük bir kaynak otomasyonunda, fonksiyonları dekoratörlerle sarmaladıktan sonra, test fonksiyonlarının isimleri aracılığıyla yansıma kullanan otomatik test sistemi bozuldu. Problem functools.wraps eksikliğiydi.


Hikaye

Günlük ekleyen bir dekoratör, *args, **kwargs kullanılmadığı için, farklı imzalı fonksiyonları desteklemiyordu. Bazı fonksiyonlar sadece Silent Fail ile bozuldu.


Hikaye

REST API'deki kimlik doğrulama projesinde, geliştirici parametrik bir dekoratör uyguladı ancak fonksiyonları doğru şekilde iç içe yerleştirmeyi unuttu (üç seviyeli iç içe yerine iki seviyeli iç içe oldu). Sonuç olarak, dekoratör parametreleri alamadı.