Словарное переключающее утверждение с действиями - PullRequest
5 голосов
/ 21 октября 2010

Я относительно новичок в Python и хотел бы знать, изобретаю ли я колесо заново или делаю что-то непитоническим способом - прочитайте неправильно.

Я переписываю какой-то парсер, изначально написанный на Lua. Существует одна функция, которая принимает имя поля из импортированной таблицы и его значение, выполняет некоторые действия со значением и сохраняет его в целевом словаре под соответствующим именем ключа.

В исходном коде это решается длинным оператором, похожим на switch, с анонимными функциями в качестве действий. Код Python выглядит следующим образом:

class TransformTable:
    target_dict = {}
    ...
    def mapfield(self, fieldname, value):
        try:
            {
                'productid': self.fn_prodid,
                'name': self.fn_name,
                'description': self.fn_desc,
                ...
            }[fieldname](value)
        except KeyError:
            sys.stderr.write('Unknown key !\n')

    def fn_name(val):
        validity_check(val)
        target_dict['Product'] = val.strip().capitalize()
    ...

Каждая функция «обработчик поля» выполняет разные действия и, конечно, хранит разные ключи в target_dict. Поскольку Python не поддерживает анонимные функции с операторами (или я что-то пропустил?), Функции должны быть написаны отдельно, что делает код менее читабельным и излишне сложным.

Будем благодарны за любые подсказки, как выполнять такие задачи более элегантным и более питоническим образом.

Thx

David

Ответы [ 2 ]

1 голос
/ 21 октября 2010

Если любым возможным способом, вы можете назвать свои функции-члены на основе имен полей и просто сделать что-то вроде этого:

getattr(self, "fn_" + fieldname)(value)

Редактировать: И вы можете использовать hasattr, чтобы проверить, существует ли функция, вместо того, чтобы ожидать KeyError. Или ожидать AttributeError. В любом случае, вы должны поместить только доступ внутри вашего try..except и вызвать его снаружи, так как в противном случае KeyError, вызванный в одном из методов поля, может быть неправильно понят.

0 голосов
/ 21 октября 2010

Я применил подход, аналогичный @Matti Virkkunen'a, недавно в своем ответе на вопрос под названием " case switch в python не работает; нужен другой шаблон ». Это также демонстрирует относительно простой и изящный способ обработки неизвестных полей. Транслитерированная в термины в вашем примере это будет выглядеть так:

class TransformTable:
    target_dict = {}

    def productid(self, value):
        ...
    def name(self, value):
        validity_check(value)
        self.target_dict['Product'] = value.strip().capitalize()
    def description(self, value):
        ...

    def _default(self, value):
        sys.stderr.write('Unknown key!\n')

    def __call__(self, fieldname, value):
        getattr(self, fieldname, self._default)(value)

transformtable = TransformTable() # create callable instance

transformtable(fieldname, value) # use it
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...