Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Изменяемые типы данных в Python
Знание изменяемых (mutable) типов данных критично при написании тестов автоматизации. Неправильное понимание может привести к неожиданному поведению и трудноуловимым ошибкам в тестах.
Что такое изменяемость
Изменяемый тип — это тип данных, содержимое которого можно изменять после создания без создания нового объекта.
Основные изменяемые типы в Python
1. List (Список)
Одна из самых часто используемых коллекций в тестировании.
users = ['Alice', 'Bob', 'Charlie']
users.append('Diana') # Добавить элемент
users[0] = 'Anna' # Изменить элемент
users.remove('Bob') # Удалить элемент
В тестах API:
- Работа с массивами из JSON
- Добавление/удаление тестовых данных
- Проверка изменения списков
2. Dictionary (Словарь)
Основной способ работы с JSON данными от API.
user = {'name': 'John', 'age': 30}
user['phone'] = '123-456-7890' # Добавить ключ
user['age'] = 31 # Изменить значение
del user['phone'] # Удалить ключ
В тестах:
- Работа с JSON ответами
- Модификация данных перед отправкой
- Проверка структуры ответов
3. Set (Множество)
Полезно для работы с уникальными значениями.
unique_ids = {1, 2, 3, 1, 2} # {1, 2, 3}
unique_ids.add(4) # Добавить элемент
unique_ids.remove(1) # Удалить элемент
Применение:
- Проверка уникальности ID
- Удаление дубликатов
- Операции множеств (объединение, пересечение)
4. Bytearray
Изменяемая версия bytes.
data = bytearray(b'hello')
data[0] = ord('H') # Изменить байт
Неизменяемые типы для сравнения
| Тип | Изменяемый | Неизменяемый |
|---|---|---|
| Последовательность | list | tuple |
| Словарь | dict | frozendict |
| Множество | set | frozenset |
| Строка | — | str |
| Байты | bytearray | bytes |
Почему это важно для тестирования
Проблема с изменяемостью
# НЕПРАВИЛЬНО: изменяемое значение по умолчанию
def create_request_body(data={}):
data['timestamp'] = time.now()
return data
request1 = create_request_body() # {'timestamp': 12345}
request2 = create_request_body() # Одновременно изменится!
# ПРАВИЛЬНО
def create_request_body(data=None):
if data is None:
data = {}
data['timestamp'] = time.now()
return data
Копирование изменяемых объектов
import copy
original = [[1, 2], [3, 4]]
shallow = original.copy() # Поверхностное копирование
deep = copy.deepcopy(original) # Глубокое копирование
shallow[0][0] = 99 # Изменит и original
deep[0][0] = 99 # original не изменится
Практический пример в тестах
def test_api_response():
response = requests.get('/api/users')
users = response.json() # Список изменяемый
# Добавляем нового пользователя для теста
users.append({'id': 999, 'name': 'Test'})
# Но оригинальные данные от API не должны измениться
assert len(response.json()) < len(users)
def test_data_isolation():
import copy
original_data = {'users': [{'id': 1}]}
test_data = copy.deepcopy(original_data)
test_data['users'].append({'id': 2})
# Оригинальные данные не изменены
assert len(original_data['users']) == 1
assert len(test_data['users']) == 2
Частые ошибки при работе с изменяемыми типами
Ошибка 1: Случайное изменение общих данных
data = [1, 2, 3]
ref = data # Не копирование, а ссылка!
ref.append(4) # Изменит и data
Ошибка 2: Незащищённые параметры функций
def process(items=[]): # Опасно!
items.append(1)
return items
Ошибка 3: Недостаточно глубокое копирование
original = {'nested': {'value': 1}}
copy_data = original.copy() # shallow copy
copy_data['nested']['value'] = 2 # Изменит original
Когда использовать изменяемые типы
- list: Для коллекций, которые будут добавляться/удаляться
- dict: Для работы с JSON данными и конфигурациями
- set: Для уникальных значений и операций множеств
- bytearray: Для обработки бинарных данных
Понимание изменяемости критично для избежания неожиданных побочных эффектов в тестах и написания надёжного кода.