Декоратор свойств @property в Python

В этом уроке вы узнаете о декораторе свойств в Python (@property) и о том, как он работает.

Что такое декоратор свойств в Python?

Ранее вы узнали, как использовать класс свойств для добавления свойства в класс. Вот синтаксис класса property:

class property(fget=None, fset=None, fdel=None, doc=None)

Ниже определяется класс Person с двумя атрибутами name и age:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

Чтобы определить метод получения для атрибута age, вы используете класс property следующим образом:

class Person:
    def __init__(self, name, age):
        self.name = name
        self._age = age

    def get_age(self):
        return self._age

    age = property(fget=get_age)

Свойство принимает геттер и возвращает объект свойства.

Следующий пример создает экземпляр класса Person и получает значение свойства age через экземпляр:

john = Person('John', 25)
print(john.age)

Выход:

25

Кроме того, вы можете напрямую вызвать метод get_age() объекта Person следующим образом:

print(john.get_age())

Таким образом, чтобы получить возраст объекта Person, вы можете использовать либо свойство age, либо метод get_age().

Чтобы избежать дублирования, вы можете переименовать метод get_age() в метод age() следующим образом:

class Person:
    def __init__(self, name, age):
        self.name = name
        self._age = age

    def age(self):
        return self._age

    age = property(fget=age)

Property() принимает вызываемый объект(age) и возвращает вызываемый объект. Следовательно, это декоратор. Поэтому вы можете использовать декоратор @property для оформления метода age() следующим образом:

class Person:
    def __init__(self, name, age):
        self.name = name
        self._age = age

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

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

Сеттер-декораторы

Следующий код добавляет метод установки (set_age) для присвоения значения атрибуту _age классу Person:

class Person:
    def __init__(self, name, age):
        self.name = name
        self._age = age

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

    def set_age(self, value):
        if value <= 0:
            raise ValueError('The age must be positive')
        self._age = value

Чтобы присвоить set_age fset объекта свойства age, вы вызываете метод setter() объекта свойства age следующим образом:

class Person:
    def __init__(self, name, age):
        self.name = name
        self._age = age

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

    def set_age(self, value):
        if value <= 0:
            raise ValueError('The age must be positive')
        self._age = value

    age = age.setter(set_age)

Метод setter() принимает вызываемый объект и возвращает другой вызываемый объект (объект свойства). Поэтому вы можете использовать декоратор @age.setter для метода set_age() следующим образом:

class Person:
    def __init__(self, name, age):
        self.name = name
        self._age = age

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

    @age.setter
    def set_age(self, value):
        if value <= 0:
            raise ValueError('The age must be positive')
        self._age = value

Теперь вы можете изменить метод set_age() на метод age() и использовать свойство age в методе __init__():

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

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

    @age.setter
    def age(self, value):
        if value <= 0:
            raise ValueError('The age must be positive')
        self._age = value

Подводя итог, вы можете использовать декораторы для создания свойства по следующему шаблону:

class MyClass:
    def __init__(self, attr):
        self.prop = attr

    @property
    def prop(self):
        return self.__attr

    @prop.setter
    def prop(self, value):
        self.__attr = value

В этом шаблоне __attr — это частный атрибут, а prop — имя свойства.

В следующем примере декораторы @property используются для создания свойств имени и возраста в классе Person:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

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

    @age.setter
    def age(self, value):
        if value <= 0:
            raise ValueError('The age must be positive')
        self._age = value

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, value):
        if value.strip() == '':
            raise ValueError('The name cannot be empty')
        self._name = value
Похожие посты
Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *