Почему `DelimitedList` и `Dict` pyparsing так неудобно использовать вместе?Python

Программы на Python
Anonymous
Почему `DelimitedList` и `Dict` pyparsing так неудобно использовать вместе?

Сообщение Anonymous »

Pyparsing предлагает подкласс ParseElementEnhance DelimitedList для анализа списков (обычно разделенных запятыми):

Код: Выделить всё

>>> kv_element = pp.Word(pp.alphanums)
>>> kv_list = pp.DelimitedList(kv_element)
>>> kv_list.parse_string('red, green, blue')
ParseResults(['red', 'green', 'blue'], {})
И он предоставляет подкласс TokenConverter Dict для преобразования повторяющегося выражения в словарь:

Код: Выделить всё

>>> key = value = pp.Word(pp.alphanums)
>>> kv_pair = key + pp.Suppress("=") + value
>>> kv_dict = pp.Dict(pp.Group(kv_pair)[...])
>>> kv_dict.parse_string('R=red G=green B=blue')
ParseResults([
ParseResults(['R', 'red'], {}),
ParseResults(['G', 'green'], {}),
ParseResults(['B', 'blue'], {})
], {'R': 'red', 'G': 'green', 'B': 'blue'})
Но объединять их неудобно. Можно создать успешный комбинированный элемент ParserElement для анализа dict из списка с разделителями, но по сравнению с приведенным выше для этого требуется:
  • Переопределение DelimitedList для вывода групп()
  • Повторение DelimitedList при построении Dict() вокруг него, чтобы успокоить тип checker.1

Код: Выделить всё

>>> kv_pair = key + pp.Suppress("=") + value
>>> kv_pairlist = pp.DelimitedList(pp.Group(kv_pair))
>>> kv_pairdict = pp.Dict(kv_pairlist[...])
>>> kv_pairdict.parse_string('R=red, G=green, B=blue')
ParseResults([
ParseResults(['R', 'red'], {}),
ParseResults(['G', 'green'], {}),
ParseResults(['B', 'blue'], {})
], {'R': 'red', 'G': 'green', 'B': 'blue'})
Весь эффект выглядит так, будто вы определяете синтаксический анализатор для создания словаря из серии списков с разделителями из 1 элемента, каждый из которых содержит одно ключевое значение. парный матч. (На самом деле, я не совсем уверен, что это на самом деле происходит в парсере.)
Написание кода для выражения намерения — определение парсера сопоставление с одним списком с разделителями, содержащим ряд совпадений пар ключ-значение, — это похоже на борьбу с API. (Особенно досадно то, что использование kv_pairdict = pp.Dict(kv_pairlist) будет функционировать так же, как указано выше, но противоречит проверке типов.)
Есть ли более понятный способ выразить предполагаемое определение синтаксического анализатора в API Pyparsing? Если нет, то является ли это недостатком моего дизайна, API Pyparsing или чего-то еще?
(У меня определение вывернуто наизнанку? DelimitedList(Dict(Group(kv_pair)[1, ...])) тоже работает, но мне кажется, что это еще более концептуально отстало. Но это не требует столько борьбы с API, так что, возможно, я просто неправильно смотрю на это.)< /p>
Примечания
  • (В противном случае, по крайней мере в VSCode, он получит эту смутно безумную аннотацию:)

    Ни один вариант перегрузки «dict» не соответствует типу аргумента
    «DelimitedList» (mypycall-overload)
    Возможные варианты перегрузки:

    Код: Выделить всё

        def [_KT, _VT] __init__(self) -> dict[_KT, _VT]
    def [_KT, _VT] __init__(self, **kwargs: _VT) -> dict[str, _VT]
    def [_KT, _VT] __init__(self, SupportsKeysAndGetItem[_KT, _VT], /) -> dict[_KT, _VT]
    def [_KT, _VT] __init__(self, SupportsKeysAndGetItem[str, _VT], /, **kwargs: _VT) -> dict[str, _VT]
    def [_KT, _VT] __init__(self, Iterable[tuple[_KT, _VT]], /) -> dict[_KT, _VT]
    def [_KT, _VT] __init__(self, Iterable[tuple[str, _VT]], /, **kwargs: _VT) -> dict[str, _VT]
    def [_KT, _VT] __init__(self, Iterable[list[str]], /) -> dict[str, str]
    def [_KT, _VT] __init__(self, Iterable[list[bytes]], /) -> dict[bytes, bytes]mypy(note)
    


Подробнее здесь: https://stackoverflow.com/questions/786 ... e-together

Вернуться в «Python»