Использование property в Python

Использование property в Python

Руководство с примерами использования функции property в языке программирования Python.

Введение

Функция property — создает вычисляемое свойство, которое позволяет использовать методы класса в качестве свойств объектов. Свойство — это аттрибут класса, который может считывать или записывать информацию. Использование property создает дескриптор, который позволяет создавать свойства объекту.

Проблема

Давайте рассмотрим пример. Существует класс человек, возраст которого не может быть меньше 0 и больше 120. Типичная ООП программа будет выглядеть примерно так:

class Human:
    """Человек, возраст которого не может быть больше 120 и меньше 0"""

    def __init__(self, age=0):
        self.set_age(age)

    def get_age(self):
        return self.age

    def set_age(self, age):
        if age < 120 and age >= 0:
            self.age = age
        else:
            self.age = 0

Как мы видим в этой реализации присутствуют некоторые проблемы и давайте их рассмотрим внимательно.

Создадим экземпляр 30 летнего человека, и проверим корректность введенных данных.

h = Human(age=30)
print(h.get_age())

30

Число 30 входит в рамки человеческой жизни и проблем у нас не возникло.

Попробуем ввести возраст вне рамок человеческой жизни

h.set_age(150)
print(h.get_age())

0

В данном примере мы обратились к методу класса, который проверил входные данные, из-за чего нам не удалось выставить некорректный возраст.

Но мы можем напрямую обратиться к аттрибуту self.age и указать абсолютно любой возраст.

h.age = 150
print(h.age)

150

Таким способом мы нарушаем алгоритм работы нашего класса, что является серьезной проблемой.

Решение

Для решения этой проблемы существуют два способа. Первый способ подразумевает использование декоратора функции, а второй способ указывает в функции property getter, setter и deleter.

Использование декоратора

@property — это декоратор, который обрабатывает получение, установку и удаление переменных класса так, как это было задумано в Python. Код для вышеописанного сценария будет выглядеть теперь так:

class Human:
    """Человек, возраст которого не может быть больше 120 и меньше 0"""

    def __init__(self, age=0):
        self.age = age

    @property
    def age(self):
        return self.__age

    @age.setter
    def age(self, age):
        if age < 120 and age >= 0:
            self.__age = age
        else:
            self.__age = 0

Наш код стал более лаконичным, но давайте разберемся по пунктам что же все таки изменилось и на что это повлияло.

  • Мы использовали декоратор @property, который создает для декорируемой функции геттер.
  • Затем мы использовали декоратор @age.setter, который создает для декорируемой функции сеттер. Сеттер определяет, что делать при установке значения переменной.

Обратите внимание, что обе функции имеют одинаковое имя. Это необходимо для работы программы.

Попробуем установить некорректное значение и посмотрим что получится:

h = Human(age=30)
h.age = 150
print(h.age)

0

Используя декоратор @property мы ограничиваем возможность указания значений переменным в классе.

Прямое указание функций

Во втором варианте использование property мы описываем функцию для установки значения и получения значения.

class Human:
    """Человек, возраст которого не может быть больше 120 и меньше 0"""

    def __init__(self, age=0):
        self.set_age(age)

    def get_age(self):
        return self.__age

    def set_age(self, age):
        if age < 120 and age >= 0:
            self.__age = age
        else:
            self.__age = 0

    age = property(get_age, set_age)

Как видите, нам просто нужно было изменить переменные и добавить специальную строку age = property(get_age, set_age), которая залатала дыры в нашем исходном коде и сэкономила нам кучу времени!

Произведем проверку

h = Human(age=30)
h.age = 150
print(h.age)

0

Все работает, как и ожидалось.

Вывод

В данном руководстве мы рассмотрели, как и для чего использовать property, воспользовались двумя вариантами реализации и проверили оба. Я не упомянул в статье о так называемых deleter, предлагаю вам сделать это самостоятельно.

Егор Егоров

Программирую на Python с 2017 года. Люблю создавать контент, который помогает людям понять сложные вещи. Не представляю жизнь без непрерывного цикла обучения, спорта и чувства юмора.

Ссылка на мой github есть в шапке. Залетай.

Оцените автора
Егоров Егор
Добавить комментарий

  1. User_test28342

    Интересно, что такое
    if age < 120 and age >= 0:
    В python нет такого

    Ответить
    1. User_test28342

      Странно, при копировании и вставке текст изменился, было
      if age & l t; 120 and age & gt ; = 0:

      Ответить
  2. Павел

    Статья понятная)мб всё ооп так разберете ? а то качественного и понятного материала не так много что бы в нём мог разобраться новичок самостоятельно)

    Ответить
    1. Егор Егоров автор

      есть же много хороших книг по ООП, не понял ничего по первой, бери читать следующую))

      Ответить