В этом уроке вы узнаете о декораторе свойств в 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
