> 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/vstroennye-dekoratory.md).

# Встроенные декораторы

### 1. **`@staticmethod`** — статический метод

* **Что делает:** превращает метод класса в обычную функцию, которая не получает `self` или `cls` автоматически.
* **Когда применять:** метод логически относится к классу, но не зависит от состояния экземпляра или самого класса.

```python
class MathUtils:
    @staticmethod
    def add(a, b):
        return a + b

print(MathUtils.add(2, 3))  # 5
```

💡 В автотестах: удобно для хелперов, например, генераторов тестовых данных.

***

### 2. **`@classmethod`** — метод класса

* **Что делает:** передаёт в метод ссылку на сам класс (`cls`) вместо экземпляра.
* **Когда применять:** нужно работать с классом в целом (например, альтернативные конструкторы).

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

    @classmethod
    def from_fullname(cls, fullname):
        first, last = fullname.split()
        return cls(first)

user = User.from_fullname("John Smith")
print(user.name)  # John
```

💡 В автотестах: полезно для фабрик объектов Page Object.

***

### 3. **`@property`** — превращает метод в атрибут

* **Что делает:** позволяет вызывать метод как обычное свойство без скобок.
* **Когда применять:** когда нужно "ленивое" вычисление значения или валидация при установке.

```python
class Rectangle:
    def __init__(self, w, h):
        self.w = w
        self.h = h

    @property
    def area(self):
        return self.w * self.h

rect = Rectangle(3, 4)
print(rect.area)  # 12
```

💡 В автотестах: удобно, когда данные должны выглядеть как атрибуты, а не методы.

***

### 4. **`@<property>.setter`** и `@<property>.deleter`

* **Что делает:** определяет логику при изменении или удалении свойства.

```python
class User:
    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

u = User("John")
u.name = "Alice"
```

***

### 5. **`@functools.lru_cache`** *(технически из `functools`, но часто относят к "встроенным")*

* **Что делает:** кеширует результат функции.
* **Когда применять:** если функция часто вызывается с одними и теми же аргументами.

```python
from functools import lru_cache

@lru_cache(maxsize=None)
def slow_calc(x):
    print("Вычисление...")
    return x * x

slow_calc(2)  # вычислит
slow_calc(2)  # возьмёт из кеша
```

💡 В тестах: удобно при работе с медленными API для повторных запросов.

***

### 6. **`@dataclass`** *(из `dataclasses`)*

* **Что делает:** автоматически создаёт `__init__`, `__repr__`, `__eq__` и другие методы для класса с атрибутами.

```python
from dataclasses import dataclass

@dataclass
class User:
    name: str
    age: int

print(User("John", 30))
```

💡 В тестах: быстро описывать структуры тестовых данных.

***

### 7. **`@abstractmethod`** *(из `abc`)*

* **Что делает:** заставляет наследников обязательно реализовать метод.

```python
from abc import ABC, abstractmethod

class BaseTest(ABC):
    @abstractmethod
    def run_test(self):
        pass
```

💡 В тестах: удобно в архитектуре, где есть общий интерфейс тестов или страниц.
