ProgramlamaKıdemli Python Geliştirici

Python'da descriptor nedir? Nasıl uygulanır, ne için kullanılır, property'den farkı nedir ve kullanımındaki tipik hatalar nelerdir?

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

Cevap

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:

  • Klasik (data descriptors) — set'i uygular, normal niteliklere göre önceliğe sahiptir;
  • Klasik olmayan (non-data descriptors) — yalnızca get'i uygular, normal niteliğe göre daha düşük önceliğe sahiptir.

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.

Aldatıcı soru

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.

Konunun incelikleri hakkında bilgi eksikliği nedeniyle ortaya çıkan gerçek hata örnekleri


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.