Data Model
Descriptors
A descriptor object lives on the class. __set_name__ lets it learn which managed attribute it is serving.
Source
class Positive:
def __set_name__(self, owner, name):
self.private_name = "_" + name
def __get__(self, obj, owner):
if obj is None:
return self
return getattr(obj, self.private_name)
def __set__(self, obj, value):
if value <= 0:
raise ValueError("must be positive")
setattr(obj, self.private_name, value)
class Product:
price = Positive()
print(Product.price.private_name)Output
_priceAssigning item.price calls Positive.__set__, and reading it calls Positive.__get__.
Source
class Product:
price = Positive()
def __init__(self, price):
self.price = price
item = Product(10)
print(item.price)
try:
item.price = -1
except ValueError as error:
print(error)Output
10
must be positiveNotes
- Descriptors are class attributes that participate in instance attribute access.
- Data descriptors with
__set__can validate or transform assignments. propertyis usually simpler for one-off managed attributes; descriptors shine when the behavior is reusable.
See also
- related: Attribute Access
- prerequisite: Properties
- related: Bound and Unbound Methods
Run the complete example
Expected output
10
_price
must be positive
Execution time appears here after you run the example.