Парсинг?

Серия Не Ван Россум

Расскажу вам о трюке, как можно обрабатывать (например, парсить) данные по какому-то ключу. Допустим, есть у нас поток с пакетами данных, которые необходимо принять и разложить по полочкам или какая-то другая задача, но наша проблема в том, что мы пишем код и понимаем, что сейчас у нас будет очень много if-ов и elif-ов и мы в них утонем.

Об оптимизации по скорости мы здесь не говорим, это просто пример.

class MyParser:

····def parse(self, some_chunk: dict) -> str:

········assert isinstance(some_chunk, dict)

········assert "action" in some_chunk

········assert "param" in some_chunk

········action, param = some_chunk["action"], some_chunk["param"]

········method = getattr(self, action, None)

········print(dir(method))

········res = method(some_chunk) if method else self.not_parsed(some_chunk)

········# Могли бы также вызвать method(param), если так будет удобней

········return res

····"""

····Здесь вся обработка полученных данных: парсинг или другое действие.

····"""

····def run(self, some_data: dict) -> str:

········"""

········Здесь действие для 'run', и так далее...

········"""

········...

········return "run processed"

····def stop(self, some_data: dict) -> str:

········...

········return "stop processed"

····def freeze(self, some_data: dict) -> str:

········...

········return "freeze processed"

····def restart(self, some_data: dict) -> str:

········...

········return "restart processed"

····def kill(self, some_data: dict) -> str:

········...

········return "kill processed"

····def info(self, some_data: dict) -> str:

········...

········return "info processed"

····def not_parsed(self, some_data):

········wtf_key = some_data["action"]

········raise RuntimeError(f"Undefined key found: {wtf_key}")

········# Или что-то другое, что должны сделать по умолчанию при

········# отсутствии обработчика такого ключа.

if __name__ == "__main__":

····data = [

········{"action": "run", "param": "some_0"},

········{"action": "stop", "param": "some_1"},

········{"action": "freeze", "param": "some_2"},

········{"action": "restart", "param": "some_3"},

········{"action": "kill", "param": "some_4"},

········{"action": "info", "param": "some_5"},

········{"action": "undefined", "param": "some_6"},

····]

····...

····mp = MyParser()

····for chunk in data:

········res = mp.parse(chunk)

········print(res)

Как видите, если у нас в классе есть обработчик для action, названный тем же именем, то мы его и вызываем. А если нет - особым образом обрабатываем такой случай.

Это кросспост из моего Telegram-канала "Не Ван Россум", где я прямо сейчас пишу сериал "101 вопрос про Python" с описанием подводных камней, неочевидностей и загвоздок.

Темы

Политика

Теги

Популярные авторы

Сообщества

18+

Теги

Популярные авторы

Сообщества

Игры

Теги

Популярные авторы

Сообщества

Юмор

Теги

Популярные авторы

Сообщества

Отношения

Теги

Популярные авторы

Сообщества

Здоровье

Теги

Популярные авторы

Сообщества

Путешествия

Теги

Популярные авторы

Сообщества

Спорт

Теги

Популярные авторы

Сообщества

Хобби

Теги

Популярные авторы

Сообщества

Сервис

Теги

Популярные авторы

Сообщества

Природа

Теги

Популярные авторы

Сообщества

Бизнес

Теги

Популярные авторы

Сообщества

Транспорт

Теги

Популярные авторы

Сообщества

Общение

Теги

Популярные авторы

Сообщества

Юриспруденция

Теги

Популярные авторы

Сообщества

Наука

Теги

Популярные авторы

Сообщества

IT

Теги

Популярные авторы

Сообщества

Животные

Теги

Популярные авторы

Сообщества

Кино и сериалы

Теги

Популярные авторы

Сообщества

Экономика

Теги

Популярные авторы

Сообщества

Кулинария

Теги

Популярные авторы

Сообщества

История

Теги

Популярные авторы

Сообщества