После некоторого времени после написания ориентированного объектно-ориентированного Python приходится точка зрения, которую вам, вероятно, нужно написать несколько Getter и Getters. В отличие от C ++, Конвенция в Python состоит в том, чтобы получить и установить свойство экземпляра класса напрямую, если нет необходимости для записи сеттера.
Например, если у нас есть Прямоугольник
класс, который имеет высота
и ширина
Свойства и методы экземпляра область
и периметр
:
class Rectangle: def __init__(self, height, width): self.height = height self.width = width def area(self): return self.height * self.width def.perimeter(self): return (self.height + self.width) * 2
Если нам никогда не нужно было проверить значения Высота
и ширина
Это было бы в порядке. Для чего угодно, как писать эксперименты в ноутбуке Jupyter, это, может быть, хорошо, но если бы мы хотели, чтобы этот код стал частью чего-то с более длинной продолжительностью жизни, как библиотека, мы, вероятно, хотим иметь что-то более надежное.
Есть некоторые вещи, которые мы знаем о прямоугольнике, на который мы должны проверить. Прямоугольники, вероятно, должны иметь только положительные высоты и ширины, поэтому мы, вероятно, должны проверить это. Вероятно, они также не должны быть нулями, поскольку это сделает его либо точку (как высота, так и ширина равна нулю), либо строка (высота, либо ширина – это ноль).
Например, мы могли бы напрямую получить доступ к Высота
и ширина
Но мы также можем напрямую изменять эти свойства для некоторого значения, которое мы знаем, неверно:
rect = Rectangle(3, 4) # Rectangle(height=3, width=4) rect.height # 3 rect.width # 4 rect.height = 0 # Should be invalid rect.width = -5 # Should also be invalid
Давайте изменим код и используем Python Getters и Setters без изменения нашего интерфейса API, обновляя __init__
Метод и добавление геттерс и поселенцев с декораторами Python @Property
для Getter и @ height.setter.
и @ width.setter.
Для установки высоты и ширины соответственно:
class Rectangle: def __init__(self, height, width): self._height = height self._width = width @property def height(self): return self._height @property def width(self): return self._width @height.setter def height(self, new_height): self._height = new_height @width.setter def width(self, new_width): self.width = new_width ...
До сих пор нет новой функциональности. Мы все еще можем установить свойства неверным значением, но мы уже можем видеть, где мы можем проверить допустимые значения – в методе, отмеченном @___. Сеттер
Отказ
@height.setter def height(self, new_height): if new_height <= 0: return self._height = new_height @width.setter def width(self, new_width): if new_width <= 0: return self.width = new_width
Поэтому после обновления посетителей мы не сможем установить _высота
и _width
свойства к чему-то недействительному. Но есть еще проблема. Мы все еще можем инициализировать наш прямоугольник _height
и _width
до недействительных значений. То, что мы хотим сделать, это использовать поселенцы в нашем __init__
Метод также. Давайте также будем поднять и исключить, а не возвращать молча:
def __init__(self, height, width): self.height = height self.width = width ... @height.setter def height(self, new_height): if new_height <= 0: raise Exception self._height = new_height @width.setter def width(self, new_width): if new_width <= 0: raise Exception self.width = new_width
Давайте также вычистите некоторую дублирование, создав статический метод для проверки достоверности значений высоты и ширины. Окончательный код должен выглядеть так с новым статическим методом check_value.
используя @staticmethod
Декоратор:
class Rectangle: def __init__(self, height, width): self.height = height self.width = width @property def height(self): return self._height @property def width(self): return self._width @height.setter def height(self, new_height): Rectangle.check_value(new_height) self._height = new_height @width.setter def width(self, new_width): Rectangle.check_value(new_width) self._width = new_width def area(self): return self.height * self.width def perimeter(self): return (self.height + self.width) * 2 @staticmethod def check_value(value): if value <= 0: raise Exception
Подход Python с GetTers и Setters – позволить вам сохранить простые программы и только использовать GetTers и Setters при необходимости без изменения интерфейса. Это довольно элегантный подход, особенно для прототипирования, не боясь меняться слишком много кода позже, когда эксперименты оказываются позже, когда вам нужно изготовить код.
Первоначально опубликовано warrenwong.org 12 апреля 2019 года.
Оригинал: “https://dev.to/wrrnwng/using-getters-and-setters-in-python-5205”