> For the complete documentation index, see [llms.txt](https://kaze.gitbook.io/qa-theory/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://kaze.gitbook.io/qa-theory/osnovy-programmirovaniya-na-python/settery-i-gettery.md).

# Сеттеры и геттеры

В Python **геттеры** и **сеттеры** — это методы для получения (get) и установки (set) значений атрибутов объекта, часто с дополнительной логикой проверки, валидации или вычислений.

В отличие от Java или C#, в Python их обычно реализуют через **`@property`** и **`@<property>.setter`**, чтобы сохранять красивый доступ через точку, но при этом иметь возможность вставить логику.

***

### 1. Классический (непитонический) способ — явные методы

```python
class Person:
    def __init__(self, name):
        self._name = name  # защищённый атрибут

    def get_name(self):
        return self._name

    def set_name(self, new_name):
        if not new_name:
            raise ValueError("Имя не может быть пустым")
        self._name = new_name

p = Person("Иван")
print(p.get_name())  # Иван
p.set_name("Мария")
```

📌 Недостаток — в Python так почти не делают, потому что это похоже на Java-стиль.

***

### 2. Питонический способ — `@property` и `@<property>.setter`

```python
class Person:
    def __init__(self, name):
        self._name = name

    @property
    def name(self):
        """Геттер"""
        return self._name

    @name.setter
    def name(self, value):
        """Сеттер"""
        if not value:
            raise ValueError("Имя не может быть пустым")
        self._name = value

p = Person("Иван")
print(p.name)   # Иван (геттер вызывается как атрибут)
p.name = "Мария"  # Сеттер
```

📌 Плюсы:

* Читается как обычный атрибут (`obj.name`), но внутри — логика.
* Можно в любой момент добавить проверки, не меняя интерфейс класса.

***

### 3. Только геттер (read-only свойство)

```python
class Circle:
    def __init__(self, radius):
        self._radius = radius

    @property
    def diameter(self):
        return self._radius * 2

c = Circle(5)
print(c.diameter)  # 10
# c.diameter = 20  # Ошибка: нет сеттера
```

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

***

### 4. Пример из автоматизации тестирования

В **Page Object Model** часто делают геттер для локаторов, чтобы не хранить их как константы и иметь возможность вычислять динамически.

```python
class LoginPage:
    def __init__(self, driver):
        self.driver = driver

    @property
    def username_field(self):
        return self.driver.find_element(By.ID, "username")

    @username_field.setter
    def username_field(self, value):
        field = self.driver.find_element(By.ID, "username")
        field.clear()
        field.send_keys(value)
```

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

```python
login_page.username_field = "test_user"  # сеттер
```
