Python

SimpleNamespace в Python: пример для настроек

SimpleNamespace из модуля types позволяет создать простой объект с полями и обращаться к ним через точку: settings.debug, settings.timeout, settings.host. Это удобно для небольших настроек, тестовых данных и сценариев, где класс писать не хочется, а словарь выглядит шумно

SimpleNamespace не заменяет полноценные модели данных. Он не проверяет типы, не валидирует значения и не защищает от случайных новых полей. Зато он прост, читается легко и хорошо подходит для маленьких конфигов

По этой теме полезно отдельно посмотреть Составьте еженедельное расписание занятий, чтобы расширить контекст и сравнить подходы

По этой теме полезно отдельно посмотреть Аннотации типов для декораторов в Python, чтобы расширить контекст и сравнить подходы

Минимальный пример

from types import SimpleNamespace

settings = SimpleNamespace(
    host='localhost',
    port=8000,
    debug=True,
)

print(settings.host)
print(settings.port)
print(settings.debug)

Результат:

localhost
8000
True

В словаре пришлось бы писать settings['host']. В SimpleNamespace можно писать settings.host, как у обычного объекта

Настройки для скрипта

Представим небольшой скрипт, который делает запросы к API

from types import SimpleNamespace

config = SimpleNamespace(
    base_url='https://api.example.com',
    timeout=15,
    retries=3,
    debug=False,
)

print(f'API: {config.base_url}')
print(f'Timeout: {config.timeout}')

Такой объект удобно передавать в функции

def print_config(config):
    mode = 'debug' if config.debug else 'production'
    print(f'Режим: {mode}')
    print(f'Повторов: {config.retries}')

print_config(config)

Если настроек мало и они не требуют строгой проверки, SimpleNamespace делает код короче

Создать SimpleNamespace из словаря

Часто настройки приходят как словарь. Его можно распаковать через **

from types import SimpleNamespace

data = {
    'host': 'localhost',
    'port': 8000,
    'debug': True,
}

settings = SimpleNamespace(**data)

print(settings.host)
print(settings.port)

Это удобно после чтения JSON, простого конфига или тестовых данных

Но есть важное ограничение: ключи словаря должны быть подходящими именами атрибутов

data = {
    'api-token': 'secret',
}

К такому полю нельзя нормально обратиться как settings.api-token. Для таких данных лучше оставить словарь или заранее нормализовать ключи

Обновить поле

Поля можно менять после создания

settings = SimpleNamespace(debug=False, retries=3)

settings.debug = True
settings.retries = 5

print(settings)

Результат будет похож на:

namespace(debug=True, retries=5)

Можно добавить новое поле:

settings.timeout = 30

Это удобно, но одновременно опасно. Если случайно написать settings.timout = 30 с ошибкой в имени, Python просто создаст новое поле. Он не скажет, что вы хотели изменить timeout

SimpleNamespace и словарь

Словарь лучше, если ключи приходят извне, могут содержать любые строки или часто перебираются в цикле

settings = {
    'host': 'localhost',
    'port': 8000,
}

for key, value in settings.items():
    print(key, value)

SimpleNamespace лучше, если набор полей маленький и вы хотите обращаться к ним как к атрибутам

settings = SimpleNamespace(host='localhost', port=8000)

print(settings.host)

Практическое правило: если данные похожи на произвольную таблицу ключей, берите dict. Если данные похожи на маленький объект настроек, можно взять SimpleNamespace

SimpleNamespace и dataclass

dataclass лучше, если нужна структура посерьезнее: понятные поля, значения по умолчанию, подсказки типов, методы, сравнение объектов

from dataclasses import dataclass

@dataclass
class Settings:
    host: str
    port: int = 8000
    debug: bool = False

settings = Settings(host='localhost')

SimpleNamespace проще, но слабее. Он не описывает структуру явно

from types import SimpleNamespace

settings = SimpleNamespace(host='localhost', port=8000, debug=False)

Если проект растет и настройки становятся важной частью приложения, лучше перейти на dataclass, Pydantic или другой инструмент конфигурации

Значения по умолчанию

Можно сделать маленькую функцию, которая собирает настройки с defaults

from types import SimpleNamespace

def make_settings(**overrides):
    defaults = {
        'host': 'localhost',
        'port': 8000,
        'timeout': 15,
        'debug': False,
    }
    defaults.update(overrides)
    return SimpleNamespace(**defaults)

settings = make_settings(debug=True, timeout=30)

print(settings.debug)
print(settings.timeout)

Так удобно в небольших скриптах и тестах, где не хочется заводить отдельный класс

Где использовать SimpleNamespace

Маленькие настройки скрипта

Тестовые данные в unit-тестах

Результат функции с несколькими именованными полями

Прототипы, где структура еще может меняться

Учебные примеры, где словарь отвлекает от основной идеи

Где не использовать

Сложная бизнес-модель

Данные, приходящие от пользователя без проверки

Большой конфиг приложения

Объекты, где важны типы и валидация

Публичный API библиотеки, который будут использовать другие разработчики

Частые ошибки

Ожидать, что SimpleNamespace проверит типы

Случайно создать новое поле из-за опечатки

Передавать в SimpleNamespace(**data) словарь с неподходящими ключами

Использовать его там, где нужен dataclass

Смешивать доступ через точку и словарный доступ. settings.host работает, а settings['host'] уже нет

Практические задачи

Создайте настройки для API-клиента: base_url, timeout, retries

Соберите SimpleNamespace из словаря через **data

Напишите функцию make_settings(), которая добавляет значения по умолчанию

Сравните один и тот же конфиг в виде словаря, SimpleNamespace и dataclass

Проверьте, что произойдет при опечатке в имени поля

SimpleNamespace — это простой способ сделать объект с полями без объявления класса. Он хорош для маленьких настроек, тестовых данных и прототипов

Если нужны строгие типы, валидация, предсказуемая структура и защита от ошибок, лучше использовать dataclass, Pydantic или обычный класс. Если ключи динамические и приходят извне, часто удобнее оставить словарь

Подписаться
Уведомить о
guest
0 комментариев
Старые
Новые Популярные

Настройки cookie

0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x