ruk·si

🐍 Python
Property Factories

Updated at 2018-06-11 02:40

Property factory are similar to attribute descriptors classes, but not as extensible.

from typing import Any

def quantity() -> property:
    try:
        quantity.counter += 1
    except AttributeError:
        quantity.counter = 0

    # we construct a name for the wrapped attribute
    # so we don't overwrite other attributes of
    # this class in the managed class
    storage_name = f'_{quantity.__name__}#{quantity.counter}'

    def qty_getter(instance: Any):
        return getattr(instance, storage_name)

    def qty_setter(instance: Any, value: Any):
        if value > 0:
            setattr(instance, storage_name, value)
        else:
            raise ValueError('value must be > 0')

    return property(qty_getter, qty_setter)

class Item:
    weight: int = quantity()

    def __init__(self, weight: int) -> None:
        self.weight = weight

# Item(-10) => ValueError
assert Item(1).weight == 1
assert Item(5).weight == 5

Sources

  • Fluent Python, Luciano Ramalho