Измените имя на Измените имя на [110] и так далее. После отправки значения будут в массиве в [111]. Это можно затем суммировать с помощью name="edible[1]"
и так далее. После отправки значения будут в массиве в
. Это можно затем суммировать с помощью array_sum()
. array_sum()
.
Python берет, "мы все соглашаемся взрослые" подход к сокрытию информации. Нормально использовать переменные, как будто они были константами и полагают, что пользователи Вашего кода не сделают чего-то глупого.
Существует недокументированный класс в re
модуль называют re.Scanner
. Это очень просто для использования для токенизатора:
import re
scanner=re.Scanner([
(r"[0-9]+", lambda scanner,token:("INTEGER", token)),
(r"[a-z_]+", lambda scanner,token:("IDENTIFIER", token)),
(r"[,.]+", lambda scanner,token:("PUNCTUATION", token)),
(r"\s+", None), # None == skip token.
])
results, remainder=scanner.scan("45 pigeons, 23 cows, 11 spiders.")
print results
приведет к
[('INTEGER', '45'),
('IDENTIFIER', 'pigeons'),
('PUNCTUATION', ','),
('INTEGER', '23'),
('IDENTIFIER', 'cows'),
('PUNCTUATION', ','),
('INTEGER', '11'),
('IDENTIFIER', 'spiders'),
('PUNCTUATION', '.')]
Я использовал ре. Сканер для записи довольно изящного синтаксического анализатора формата конфигурации/структурированных данных только в паре сотни строк.
"Есть ли лучшая альтернатива просто возврату списка кортежей?"
Нет. Это работает действительно хорошо.
Спасибо за Вашу справку я начал объединять эти идеи, и я придумал следующее. Есть ли что-либо ужасно неправильно с этой реализацией (особенно я обеспокоен передачей объекта файла к токенизатору):
class Tokenizer(object):
def __init__(self,file):
self.file = file
def __get_next_character(self):
return self.file.read(1)
def __peek_next_character(self):
character = self.file.read(1)
self.file.seek(self.file.tell()-1,0)
return character
def __read_number(self):
value = ""
while self.__peek_next_character().isdigit():
value += self.__get_next_character()
return value
def next_token(self):
character = self.__peek_next_character()
if character.isdigit():
return self.__read_number()
Во многих ситуациях, экспорте при парсинге длинных входных потоков, можно найти более полезным реализовать Вас токенизатор как функция генератора. Таким образом, можно легко выполнить итерации по всем маркерам без потребности в большой памяти для создания списка маркеров сначала.
Поскольку генератор видит первоначальное предложение или другие документы онлайн
"Есть ли лучшая альтернатива просто возврату списка кортежей?"
Это - подход, используемый "маркировать" модулем для парсинга исходного кода Python. Возврат простого списка кортежей может работать очень хорошо.
Я недавно создал токенизатор также и прошел через некоторые Ваши проблемы.
Типы маркера объявляются как "константы", т.е. переменные с именами ALL_CAPS, на уровне модуля. Например,
_INTEGER = 0x0007
_FLOAT = 0x0008
_VARIABLE = 0x0009
и так далее. Я использовал подчеркивание перед именем, чтобы указать, что так или иначе те поля являются "частными" за модуль, но я действительно не знаю, типично ли это или желательно, даже сколько Pythonic. (Кроме того, я, вероятно, угроблю числа в пользу строк, потому что во время отладки они намного более читаемы.)
Маркеры возвращаются как названные кортежами.
from collections import namedtuple
Token = namedtuple('Token', ['value', 'type'])
# so that e.g. somewhere in a function/method I can write...
t = Token(n, _INTEGER)
# ...and return it properly
Я использовал названные кортежи, потому что клиентский код токенизатора (например, синтаксический анализатор) кажется немного более четким при использовании имен (например, token.value) вместо индексов (например, маркер [0]).
Наконец, я заметил, что иногда, особенно пишущий тесты, предпочитаю передавать строку токенизатору вместо объекта файла. Я называю это "читателем" и имею определенный метод, чтобы открыть его и позволить токенизатору получить доступ к нему через тот же интерфейс.
def open_reader(self, source):
"""
Produces a file object from source.
The source can be either a file object already, or a string.
"""
if hasattr(source, 'read'):
return source
else:
from io import StringIO
return StringIO(source)
Когда я запускаю что-то новое в Python, я обычно смотрю сначала на некоторые модули или библиотеки для использования. Существует 90% + шанс, что уже существует что-то доступное.
Для токенизаторов и синтаксических анализаторов это, конечно, так. Вы посмотрели на PyParsing?
"Есть ли лучшая альтернатива просто возврату списка кортежей"
Я должен был реализовать токенизатор, но он потребовал более сложного подхода, чем список кортежей, поэтому я реализовал класс для каждого маркера. Можно затем возвратить список экземпляров класса, или если Вы хотите сохранить ресурсы, можно возвратиться, что-то, реализовывая итератор соединяет интерфейсом и генерирует следующий маркер, в то время как Вы прогрессируете в парсинге.
Я бы обратился к превосходной Обработке текста в Python Дэвида Мертца
Я реализовал токенизатор для C-подобного языка программирования. Я разделил создание токенов на два уровня:
Оба являются генераторами. Преимущества этого подхода заключались в следующем:
Я вполне счастлив с этим многоуровневым подходом.
с простыми регулярными выражениями - быстро и чисто.Я вполне счастлив с этим многоуровневым подходом.
с простыми регулярными выражениями - быстро и чисто.Я вполне счастлив с этим многоуровневым подходом.