Descriptor, get, set ve delete yöntemlerinden herhangi birini uygulayan bir nesnedir. Sınıfın niteliklerine erişimi kontrol etmenizi sağlar.
Descriptor'ın standart yöntemleri:
__get__(self, instance, owner)__set__(self, instance, value)__delete__(self, instance)Descriptor'lar:
Kullanım örneği:
class OnlyPositive: def __init__(self): self._name = '_value' def __get__(self, instance, owner): return instance.__dict__[self._name] def __set__(self, instance, value): if value < 0: raise ValueError('Değer 0 veya daha büyük olmalı') instance.__dict__[self._name] = value class Account: value = OnlyPositive() def __init__(self, value): self.value = value acc = Account(10) acc.value = -1 # ValueError!
property — sınıf düzeyinde descriptor oluşturmak için yalnızca bir sözdizim şeklidir.
Eğer descriptor bir örnek niteliği olarak değil de bir sınıf niteliği olarak oluşturulursa ne olur?
Birçok kişi descriptor'ın çalışacağını düşünmektedir, ancak bu doğru değildir.
Doğru cevap:
Descriptor, yalnızca sınıf niteliği olarak belirlenirse çalışır. Bir descriptor'ı bir örnek niteliği olarak atarsanız, get/set yöntemleri çağrılmaz — bu, niteliğe erişim mantığıdır.
Hikaye
Tam bir descriptor yerine property kullanımı
Doğrulama ve diğer ilişkili nitelikler için geliştirici basit bir property kullandı, bu da sık sık mantığın kopyalanmasına ve farklı sınıflar arasında kodun yeniden kullanılmasının imkansız olmasına yol açtı.
Hikaye
Depolamanın yeniden kullanımında değişmezliğe uyulmaması
Descriptor, verileri kendi sınıfının iç niteliğinde (self.x) saklarken, örneğin iç depolama alanında değil, bu nedenle nitelik "ortak" hale geldi ve sınıfın farklı örnekleri birbirlerinin değerlerini yazabiliyor — veriler nesneler arasında "sızabiliyordu".
Hikaye
Data descriptor ve non-data descriptor'ın karıştırılması
Karmaşık bir hiyerarşide set uygulaması atlandı, bu nedenle normal bir örnek niteliği descriptor'ı geçersiz kıluyordu ve tüm doğrulama mekanizmasını bozuyordu — hata her zaman ortaya çıkmıyordu, hata ayıklaması zor hale geliyordu.