Descriptor là object định nghĩa cách attribute được truy cập — cơ chế ẩn sau @property, @classmethod, @staticmethod.
python
class Validator:
"""Non-data descriptor (chỉ __get__)"""
def __set_name__(self, owner, name):
self.name = name
def __get__(self, obj, objtype=None):
if obj is None: return self # Access từ class
return obj.__dict__.get(self.name)
def __set__(self, obj, value):
# Data descriptor — có cả __set__
if not isinstance(value, int) or value < 0:
raise ValueError(f"{self.name} phải là số nguyên không âm")
obj.__dict__[self.name] = value
class Product:
price = Validator() # Descriptor instance làm class attribute
quantity = Validator()
p = Product()
p.price = 100 # Gọi Validator.__set__
p.price = -1 # ValueError!Data descriptor (có __set__): ưu tiên hơn instance __dict__. Non-data descriptor (chỉ __get__): instance __dict__ ưu tiên hơn.
Hiểu Descriptor giải thích tại sao instance.method trả về bound method.