shlex.md
1> **Источник:** https://python-all.ru/3.1/library/shlex.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 23.3. `shlex` – Простой лексический анализ89Класс [`shlex`](https://python-all.ru/3.1/library/shlex.html#shlex.shlex) упрощает написание лексических анализаторов для простых синтаксисов, напоминающих синтаксис оболочки Unix. Это часто бывает полезно при написании мини-языков (например, в файлах конфигурации для приложений Python) или для разбора строк в кавычках.1011Модуль `shlex` определяет следующие функции:1213#### `shlex.split(s[, comments[, posix]])`1415Разбивает строку *s*, используя синтаксис, подобный шелл-синтаксису. Если *comments* равно [`False`](https://python-all.ru/3.1/library/constants.html#False) (значение по умолчанию), разбор комментариев в данной строке будет отключён (при этом атрибут `commenters` экземпляра [`shlex`](https://python-all.ru/3.1/library/shlex.html#shlex.shlex) устанавливается в пустую строку). Эта функция по умолчанию работает в режиме POSIX, но использует не-POSIX режим, если аргумент *posix* равен false.1617> **Примечание**18>19> Поскольку функция [`split()`](https://python-all.ru/3.1/library/shlex.html#shlex.split) создаёт экземпляр [`shlex`](https://python-all.ru/3.1/library/shlex.html#shlex.shlex), передача `None` в качестве *s* приведёт к чтению строки для разбиения из стандартного ввода.2021Модуль `shlex` определяет следующий класс:2223#### `class shlex.shlex([instream[, infile[, posix]]])`2425Экземпляр2627[`shlex`](https://python-all.ru/3.1/library/shlex.html#shlex.shlex)2829или его подкласса представляет собой объект лексического анализатора. Аргумент инициализации (если указан) определяет источник символов. Это должен быть файлоподобный или потокоподобный объект с методами3031`read()`3233и3435`readline()`3637, либо строка. Если аргумент не указан, ввод будет производиться из3839`sys.stdin`4041. Второй необязательный аргумент – это строка с именем файла, которая задаёт начальное значение атрибута4243[`infile`](https://python-all.ru/3.1/library/shlex.html#shlex.shlex.infile)4445. Если аргумент4647*instream*4849опущен или равен5051`sys.stdin`5253, то второй аргумент по умолчанию принимает значение “stdin”. Аргумент5455*posix*5657определяет режим работы: если5859*posix*6061не истинно (по умолчанию), экземпляр6263[`shlex`](https://python-all.ru/3.1/library/shlex.html#shlex.shlex)6465будет работать в режиме совместимости. При работе в режиме POSIX6667[`shlex`](https://python-all.ru/3.1/library/shlex.html#shlex.shlex)6869будет стараться максимально точно следовать правилам разбора POSIX-шелла.7071> **См. также**72>73> **Модуль [`configparser`](https://python-all.ru/3.1/library/configparser.html#module-configparser)**74>75> Парсер конфигурационных файлов, похожих на файлы Windows76>77> `.ini`78>79> .8081## 23.3.1. Объекты shlex8283Экземпляр [`shlex`](https://python-all.ru/3.1/library/shlex.html#shlex.shlex) имеет следующие методы:8485#### `shlex.get_token()`8687Возвращает токен. Если токены были помещены в стек с помощью8889[`push_token()`](https://python-all.ru/3.1/library/shlex.html#shlex.shlex.push_token)9091, извлекает токен из стека. В противном случае читает один токен из входного потока. Если при чтении немедленно достигается конец файла, возвращается9293`self.eof`9495(пустая строка (9697`''`9899) в не-POSIX режиме и100101`None`102103в режиме POSIX).104105#### `shlex.push_token(str)`106107Помещает аргумент в стек токенов.108109#### `shlex.read_token()`110111Читает сырой токен. Игнорирует стек возврата и не интерпретирует запросы источника. (Обычно это не является полезной точкой входа и документируется здесь только для полноты.)112113#### `shlex.sourcehook(filename)`114115Когда [`shlex`](https://python-all.ru/3.1/library/shlex.html#shlex.shlex) обнаруживает запрос источника (см. [`source`](https://python-all.ru/3.1/library/shlex.html#shlex.shlex.source) ниже), этому методу передается следующий токен в качестве аргумента, и ожидается, что он вернет кортеж, состоящий из имени файла и открытого объекта, подобного файлу.116117Обычно этот метод сначала удаляет кавычки из аргумента. Если результат является абсолютным путём, или нет активного предыдущего запроса исходного файла, или предыдущий источник был потоком (например, `sys.stdin`), результат оставляется без изменений. В противном случае, если результат является относительным путём, к нему добавляется каталог файла, находящегося непосредственно перед ним в стеке включения исходных файлов (это поведение похоже на то, как препроцессор C обрабатывает `#include "file.h"`).118119Результат манипуляций рассматривается как имя файла и возвращается в качестве первого компонента кортежа, а для получения второго компонента вызывается [`open()`](https://python-all.ru/3.1/library/functions.html#open) с этим именем. (Примечание: это обратный порядок аргументов при инициализации экземпляра!)120121Этот хук предоставляется, чтобы вы могли использовать его для реализации путей поиска по каталогам, добавления расширений файлов и других трюков с пространством имен. Соответствующего хука 'close' нет, но экземпляр shlex вызовет метод `close()` входного потока источника, когда тот достигнет EOF.122123Для более явного управления стеком источников используйте методы [`push_source()`](https://python-all.ru/3.1/library/shlex.html#shlex.shlex.push_source) и [`pop_source()`](https://python-all.ru/3.1/library/shlex.html#shlex.shlex.pop_source).124125#### `shlex.push_source(stream[, filename])`126127Помещает входной поток-источник в стек ввода. Если указан аргумент имени файла, он будет доступен для использования в сообщениях об ошибках. Это тот же метод, который используется внутри метода128129[`sourcehook()`](https://python-all.ru/3.1/library/shlex.html#shlex.shlex.sourcehook)130131.132133#### `shlex.pop_source()`134135Извлекает последний помещённый входной источник из стека ввода. Это тот же метод, который используется внутри, когда лексер достигает EOF для помещённого в стек входного потока.136137#### `shlex.error_leader([file[, line]])`138139Этот метод генерирует заголовок сообщения об ошибке в формате метки ошибки компилятора C в Unix; формат: `'"%s", line %d: '`, где `%s` заменяется именем текущего исходного файла, а `%d` – номером текущей строки ввода (необязательные аргументы можно использовать для переопределения этих значений).140141Эта удобная функция предоставляется, чтобы побудить пользователей `shlex` генерировать сообщения об ошибках в стандартном, разбираемом формате, который понимают Emacs и другие инструменты Unix.142143Экземпляры подклассов [`shlex`](https://python-all.ru/3.1/library/shlex.html#shlex.shlex) имеют некоторые открытые переменные экземпляра, которые либо управляют лексическим анализом, либо могут использоваться для отладки:144145#### `shlex.commenters`146147Строка символов, которые распознаются как начало комментария. Все символы от начала комментария до конца строки игнорируются. По умолчанию включает только148149`'#'`150151.152153#### `shlex.wordchars`154155Строка символов, которые будут накапливаться в составные токены. По умолчанию включает все буквы и цифры ASCII и символ подчёркивания.156157#### `shlex.whitespace`158159Символы, которые считаются пробельными и пропускаются. Пробельные символы разделяют токены. По умолчанию включает пробел, табуляцию, перевод строки и возврат каретки.160161#### `shlex.escape`162163Символы, которые будут считаться экранирующими. Это используется только в режиме POSIX и по умолчанию включает только164165`'\'`166167.168169#### `shlex.quotes`170171Символы, которые будут считаться строковыми кавычками. Токен накапливается до тех пор, пока не встретится та же самая кавычка (то есть разные типы кавычек защищают друг друга, как в оболочке). По умолчанию включает ASCII одинарные и двойные кавычки.172173#### `shlex.escapedquotes`174175Символы в176177[`quotes`](https://python-all.ru/3.1/library/shlex.html#shlex.shlex.quotes)178179, которые будут интерпретировать escape-символы, определённые в180181[`escape`](https://python-all.ru/3.1/library/shlex.html#shlex.shlex.escape)182183. Это используется только в режиме POSIX и по умолчанию включает только184185`'"'`186187.188189#### `shlex.whitespace_split`190191Если192193`True`194195, токены будут разделяться только по пробелам. Это полезно, например, для разбора командных строк с помощью196197[`shlex`](https://python-all.ru/3.1/library/shlex.html#shlex.shlex)198199, получая токены аналогично аргументам оболочки.200201#### `shlex.infile`202203Имя текущего входного файла, установленное при создании экземпляра класса или помещённое в стек последующими запросами источников. Может быть полезно просмотреть его при формировании сообщений об ошибках.204205#### `shlex.instream`206207Входной поток, из которого данный экземпляр208209[`shlex`](https://python-all.ru/3.1/library/shlex.html#shlex.shlex)210211читает символы.212213#### `shlex.source`214215По умолчанию этот атрибут равен216217`None`218219. Если присвоить ему строку, эта строка будет распознаваться как запрос на включение на лексическом уровне, аналогичный ключевому слову220221`source`222223в различных оболочках. То есть следующий сразу за ним токен будет открыт как имя файла, и ввод будет производиться из этого потока до EOF, после чего будет вызван метод224225`close()`226227этого потока, и источником ввода снова станет исходный поток. Запросы на включение могут быть вложены на любую глубину.228229#### `shlex.debug`230231Если этот атрибут является числовым и больше или равен232233`1`234235, экземпляр236237[`shlex`](https://python-all.ru/3.1/library/shlex.html#shlex.shlex)238239будет выводить подробную информацию о своих действиях. Если потребуется воспользоваться этим, можно прочитать исходный код модуля, чтобы узнать детали.240241#### `shlex.lineno`242243Номер строки в исходном файле (количество встреченных символов новой строки плюс один).244245#### `shlex.token`246247Буфер токенов. Его может быть полезно проверить при перехвате исключений.248249#### `shlex.eof`250251Токен, используемый для определения конца файла. В не-POSIX режиме он устанавливается в пустую строку (252253`''`254255), а в POSIX режиме – в256257`None`258259.260261## 23.3.2. Правила разбора262263При работе в не-POSIX режиме [`shlex`](https://python-all.ru/3.1/library/shlex.html#shlex.shlex) будет стараться следовать следующим правилам.264265- Символы кавычек не распознаются внутри слов (`Do"Not"Separate` разбирается как одно слово `Do"Not"Separate`);266- Символы экранирования не распознаются;267- Заключение символов в кавычки сохраняет буквальное значение всех символов внутри кавычек;268- Закрывающие кавычки разделяют слова (`"Do"Separate` разбирается как `"Do"` и `Separate`);269- Если `whitespace_split` равно `False`, любой символ, не объявленный как символ слова, пробел или кавычка, будет возвращен как односимвольный токен. Если же оно равно `True`, [`shlex`](https://python-all.ru/3.1/library/shlex.html#shlex.shlex) будет разбивать слова только по пробелам;270- EOF обозначается пустой строкой (`''`);271- Невозможно разобрать пустые строки, даже если они в кавычках.272273При работе в режиме POSIX [`shlex`](https://python-all.ru/3.1/library/shlex.html#shlex.shlex) будет пытаться следовать следующим правилам разбора.274275- Кавычки удаляются и не разделяют слова (`"Do"Not"Separate"` разбирается как одно слово `DoNotSeparate`);276- Неэкранированные (не в кавычках) escape-символы (например, `'\'`) сохраняют буквальное значение следующего за ними символа;277- Заключение символов в кавычки, которые не входят в `escapedquotes` (например, `"'"`), сохраняет буквальное значение всех символов внутри кавычек;278- Заключение символов в кавычки, которые входят в `escapedquotes` (например, `'"'`), сохраняет буквальное значение всех символов внутри кавычек, за исключением символов, указанных в `escape`. Символы экранирования сохраняют своё специальное значение только тогда, когда за ними следует используемая кавычка или сам символ экранирования. В противном случае символ экранирования считается обычным символом.279- EOF обозначается значением [`None`](https://python-all.ru/3.1/library/constants.html#None);280- Пустые строки в кавычках (`''`) разрешены;281