Her @property, classmethod, staticmethod ve hatta normal metot çağrılarınızın altında aynı mekanizma çalışır: Tanımlayıcılar (descriptors).

Tanımlayıcı, protokol yöntemlerinden en az birini uygulayan herhangi bir sınıftır: __get__, __set__ veya __delete__. Böyle bir sınıfın örneğini başka bir sınıfın niteliğine bağladığınızda, Python erişim kontrolünü devralır.

1️⃣ Öncelik Hiyerarşisi
obj.attr yazdığınızda, Python doğrudan sözlüğe bakmaz. Katı bir zincir izler:
▪️ Data Descriptor (__set__ veya __delete__ tanımlanmış). Mutlak önceliğe sahiptir. Nitelik adı bir Data tanımlayıcı tarafından ele geçirilirse, Python instance.__dict__'yi umursamaz. Bu nedenle, @property'yi (setter yoksa) normal atama ile geçersiz kılamazsınız.
▪️ Örnek sözlüğü (__dict__). Nesnenin normal verileri.
▪️ Non-Data Descriptor (yalnızca __get__ tanımlanmış). Normal sınıf metotları bunlardır. Öncelik sırasının en altındadırlar. Nesnenin __dict__'sine metot adıyla bir fonksiyon koyarsanız, orijinal metodu geçersiz kılar.

2️⃣ Paylaşılan Durum Anti-Deseni
Tanımlayıcı, örnek düzeyinde değil, sınıf düzeyinde başlatılır. Herkes için tektir. Tanımlayıcı örneğinin içinde veri saklarsanız, bu değeri sınıfınızın tüm nesneleri için üzerine yazarsınız. Vasya yaşını değiştirirse, Petya da onunla birlikte aniden yaşlanır, çünkü her iki örnek de aynı tanımlayıcı bellek hücresine erişir.

Doğru nasıl yazılır?
Durum, kesinlikle örneğin kendi sözlüğünde saklanmalıdır. Geçici çözümler yazmamak için Python 3.6+ ile __set_name__ sihirli metodu getirildi. Bu, tanımlayıcının sınıfta hangi adla oluşturulduğunu bilmesini sağlar, böylece verileri belirli bir nesnenin __dict__'sine yasal olarak kaydedebilir.

class Validator:
def __set_name__(self, owner, name):
# Nitelik adını hatırla, sabit kodlama yapma
self.private_name = f"_{name}"

def __get__(self, instance, owner):
if instance is None:
return self
return getattr(instance, self.private_name)

def __set__(self, instance, value):
# ✅ Verileri yalnızca BELİRLİ örneğin sözlüğüne yaz
if not isinstance(value, int):
raise TypeError("Yalnızca tam sayılara izin verilir")
setattr(instance, self.private_name, value)

class User:
age = Validator() # age_validator.__set_name__ name='age' alır


Tanımlayıcılar, mantığı kapsüllemek için son derece güçlü bir araçtır. Django veya SQLAlchemy gibi çerçevelerin tüm sihri bunlar üzerine inşa edilmiştir ☝️

#anatomi_piton