Что такое property в Python и для чего он используется

Ответ

property — это встроенная функция в Python, которая чаще всего используется как декоратор для создания управляемых атрибутов (managed attributes). Она позволяет превратить методы класса в атрибуты, доступ к которым (чтение, запись, удаление) контролируется специальными методами (геттер, сеттер, делитер).

Основная цель — обеспечить инкапсуляцию, добавив логику при работе с атрибутами, не изменяя при этом публичный API класса.

Пример: Управление доступом к атрибуту

class Account:
    def __init__(self, initial_balance):
        # Приватный атрибут для хранения баланса
        self._balance = initial_balance

    @property
    def balance(self):
        """Геттер: возвращает значение баланса."""
        print("Вызван геттер для balance")
        return self._balance

    @balance.setter
    def balance(self, value):
        """Сеттер: проверяет значение перед установкой."""
        print("Вызван сеттер для balance")
        if value < 0:
            raise ValueError("Баланс не может быть отрицательным")
        self._balance = value

    @balance.deleter
    def balance(self):
        """Делитер: логика при удалении атрибута."""
        print("Вызван делитер для balance")
        del self._balance

# Использование
acc = Account(1000)

# Чтение (вызывает геттер)
current_balance = acc.balance 
print(f"Текущий баланс: {current_balance}")

# Запись (вызывает сеттер)
acc.balance = 1200

# Попытка установить неверное значение (вызовет ValueError)
try:
    acc.balance = -50
except ValueError as e:
    print(f"Ошибка: {e}")

# Удаление (вызывает делитер)
del acc.balance

Ключевые преимущества:

  1. Контролируемый доступ: Позволяет добавить валидацию или логирование при чтении/записи атрибутов.
  2. API Stability: Можно начать с простого публичного атрибута, а позже заменить его на property без изменения кода, который использует этот класс.
  3. "Вычисляемые" атрибуты: Геттер может возвращать не сохраненное значение, а результат вычислений на основе других атрибутов.