Свойства особенно полезны, когда вы хотите получить прямой доступ к атрибутам объекта и в некоторых случаях вам нужно иметь дополнительный код вокруг методов получения / установки.
Представьте, что у вас есть автомобильный объект.
class Car(object):
def __init__(self, make, model, year, vin):
self.make = make
self.model = model
self.year = year
self.vin = vin
my_car = Car('Ford', 'Taurus', 2005, '123ABCVINSARELONG999')
А теперь представьте, что мне нужно поменять год на машине.Я мог бы сделать это несколькими разными способами.
my_car.year = 2006
my_car.year = '2007'
Второй способ доставляет мне серьезные проблемы, если я хочу предположить, что год - это число.См. Следующее:
if(my_car.year > 2010):
print('Shiney new!')
Проблема в том, что установка атрибутов напрямую очень чистая и удобная, но не дает нам возможности проводить какую-либо проверку данных (возможно, я хочу убедиться, что марка находится в спискенапример, известных производителей) или преобразование типов данных (в примере года).
Свойства приходят на помощь, позволяя нам настраивать код оболочки вокруг назначения и / или извлечения атрибута, но не требуя, чтобы мы это делалидля всех атрибутов или даже требует от нас заранее знать, что мы хотим сделать дополнительную проверку.После этого я могу изменить свой объект Car следующим образом, и он все равно будет использоваться точно таким же образом.
class Car(object):
def __init__(self, make, model, year, vin):
self.make = make
self.model = model
self._year = year
self.vin = vin
def get_year(self):
return self._year
def set_year(self, val):
self._year = int(val)
year = property(get_year, set_year)
Вы по-прежнему используете год как my_car.year
, и вы по-прежнему устанавливаете его с * 1018.*, но теперь он конвертирует значение в int, где это необходимо, и выдает исключение, если значение, предоставленное пользователем, не преобразуется в int должным образом.