ProgramlamaBackend Python Geliştiricisi

Python'da sınıf özelliklerinin dekoratörleri (@property) nedir, nasıl çalışır ve ne için gereklidir?

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

Yanıt.

@property dekoratörü, bir metodu sınıfın "sanal" bir niteliğine dönüştürmeyi sağlar: sınıf kullanıcıları için normal bir özellik gibi görünür, ancak Python fonksiyonunun mantığıyla yönetilir. Python'da başlangıçta, tüm örnek nitelikleri doğrudan erişilebilirken, kapsüllemeyi desteklemek için veri erişim mantığını değiştirmeden veri erişimini yönetme mekanizmasına ihtiyaç duyulmuştur.

Tarihçe:

Python'un erken sürümlerinde, niteliklere erişimi kısıtlama konusunda açık bir mekanizma yoktu. Kapsülleme sorunu, anlaşmalar (örneğin, alt çizgi kullanarak) aracılığıyla çözülmüştü, ancak değerlerin saklanması/gevşekliği ile ilgili mantıktaki herhangi bir değişiklik uyumluluğu bozabiliyordu. @property dekoratörünün ortaya çıkmasıyla, bir metodu nitelik olarak ilan etme, ona alıcı, ayarlayıcı ve silici ekleme fırsatı doğmuş oldu ve bu şekilde sınıfın eski arayüzü korundu.

Sorun:

Sonradan bir alanın doğrulama veya hesaplama mantığını eklemek gerektiğinde, tüm arayüzü yeniden yapılandırmak çok maliyetli olabilir — değişkenle erişim yerlerinin hepsini değiştirmek gerekir. Bu arada, alanın iç mantığının sınıf dışındaki kullanıcılara açılmaması gerekmektedir. @property, erişimi kolayca "sanal hale getirmeyi" sağlar.

Çözüm:

@property, "aracı/ayarlayıcı ile arayüz koruma" desenini uygular: hesaplanabilir bir özellik ekleyebilir veya değerin ayarlanmasını kontrol edebilirsiniz, böylece istemci kodunu değiştirmeden yapabilirsiniz.

Kod örneği:

class Sıcaklık: def __init__(self, celsius): self._celsius = celsius @property def celsius(self): return self._celsius @celsius.setter def celsius(self, deger): if deger < -273.15: raise ValueError("Sıcaklık mutlak sıfırın altında!") self._celsius = deger @property def fahrenheit(self): return self._celsius * 9 / 5 + 32 # Kullanım obj = Sıcaklık(25) print(obj.celsius) # 25 print(obj.fahrenheit) # 77.0 obj.celsius = -300 # ValueError

Anahtar özellikler:

  • Müşteri arayüzünü değiştirmeden, hesaplanabilir, doğrulamalı veya önbellek özelliği uygulamayı sağlar
  • Özellik arayüzü sunar (erişimde parantez yok)
  • Hem okuma, hem yazma ve değerin silinmesini kontrol etmeye izin verir

Kandırmaca soruları.

Herhangi bir sınıf alanına property eklemek mümkün mü, geriye uyumluluğu bozmadan?

Hayır. Eğer nitelik kamuya açık olarak tanıtıldı ve normal değişken gibi kullanıldıysa, property'e geçiş şeffaf bir şekilde yapılabilir. Ancak eğer bir yerlerde __dict__ üzerinden erişim veya type(obj.attr) ile tür kontrolü yapıldıysa, beklenmeyen bir davranış olabilir.

Bir özellik için sadece ayarlayıcı (setter) tanımlanabilir mi, alıcı (getter) olmadan?

Hayır, öncelikle bir alıcı (veya @property ile bir metot) zorunludur; aksi taktirde Python, ayarlayıcıyı hangi özelliğe "bağlayacağını" bilemez.

@property/@setter/@deleter dekoratörlerinin sırası nedir ve neden?

Her zaman önce @property yazılır (bu, özellik nesnesini oluşturur), ardından metod adıyla @<isim>.setter ve @<isim>.deleter yazılır (bu, daha önceki oluşturulan property'i tamamlar).

class A: @property def value(self): ... @value.setter def value(self, v): ...

Tipik hatalar ve anti-deseni

  • Sınıf dışında (örn. self._celsius) kapalı niteliğe doğrudan erişim
  • Kapsülleme ilkesinin ihlali: alıcı/ayarlayıcıda fazladan mantık
  • Kalıtımlarda isim çakışması ile property'nin yeniden tanımlanması

Gerçek hayattan bir örnek

Olumsuz durum

Sınıf alanları kamuya açıkken, sonra kamu API'si yayımlandıktan sonra property ile hesaplanabilir özellik eklendi. Eski kodda niteliğe erişim, davranışı kaydırabilir veya hata oluşturabilir.

Artılar:

  • Kullanıcı, özelliğe erişim yöntemlerini değiştirmek zorunda kalmaz.

Eksiler:

  • Erişim koşulu ayarlayıcı/alıcı mantığı haline geldiğinde, kodda beklenmeyen hatalar meydana gelebilir.
  • Eğer istemci doğrudan dict'ye erişmişse, uyumluluk düşük olabilir.

Olumlu durum

Alanlar tasarlandığında, kapalı olarak belirlendi (bir alt çizgi ile) ve kullanıcılar sadece metotlar veya özellikler aracılığıyla çalışmaya alışkın oldu. Gelecekte property'de yeni bir mantık eklenmesi, istemci arayüzünde hiçbir değişiklik olmadan geçti.

Artılar:

  • Kapsülleme
  • Kolayca doğrulama ve hesaplamalar ekleme imkanı

Eksiler:

  • Belge disiplini ve anlaşmalara uyulmasını gerektirir; zayıf gizlilik (bir alt çizgi, tam koruma için yeterli değildir)