Документация Python неофициальный перевод

shlex.md

198 строк · 20.8 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/3.5/library/shlex.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 24.3. [`shlex`](https://python-all.ru/3.5/library/shlex.html#module-shlex) – Простой лексический анализ89**Исходный код:** [Lib/shlex.py](https://python-all.ru/src/3.5/Lib/shlex.py)1011---1213Класс [`shlex`](https://python-all.ru/3.5/library/shlex.html#shlex.shlex) упрощает написание лексических анализаторов для синтаксиса, напоминающего синтаксис оболочки Unix. Это часто бывает полезно для создания мини-языков (например, в конфигурационных файлах приложений Python) или для разбора строк в кавычках.1415Модуль [`shlex`](https://python-all.ru/3.5/library/shlex.html#module-shlex) определяет следующие функции:1617#### `shlex.split(s, comments=False, posix=True)`1819Разделяет строку *s*, используя синтаксис, подобный оболочке. Если *comments* равно [`False`](https://python-all.ru/3.5/library/constants.html#False) (по умолчанию), разбор комментариев в заданной строке будет отключён (устанавливает атрибут [`commenters`](https://python-all.ru/3.5/library/shlex.html#shlex.shlex.commenters) экземпляра [`shlex`](https://python-all.ru/3.5/library/shlex.html#shlex.shlex) в пустую строку). Эта функция работает в режиме POSIX по умолчанию, но использует не-POSIX режим, если аргумент *posix* равен False.2021> **Примечание**22>23> Поскольку функция [`split()`](https://python-all.ru/3.5/library/shlex.html#shlex.split) создаёт экземпляр [`shlex`](https://python-all.ru/3.5/library/shlex.html#shlex.shlex) , передача `None` в качестве *s* будет читать строку для разбиения из стандартного ввода.2425#### `shlex.quote(s)`2627Возвращает экранированную для оболочки версию строки *s*. Возвращаемое значение – это строка, которую можно безопасно использовать как один токен в командной строке оболочки в тех случаях, когда нельзя использовать список.2829Этот подход был бы небезопасен:3031```python32>>> filename = 'somefile; rm -rf ~'33>>> command = 'ls -l {}'.format(filename)34>>> print(command)  # выполнено оболочкой: бабах!35ls -l somefile; rm -rf ~36```3738[`quote()`](https://python-all.ru/3.5/library/shlex.html#shlex.quote) позволяет закрыть брешь в безопасности:3940```python41>>> command = 'ls -l {}'.format(quote(filename))42>>> print(command)43ls -l 'somefile; rm -rf ~'44>>> remote_command = 'ssh home {}'.format(quote(command))45>>> print(remote_command)46ssh home 'ls -l '"'"'somefile; rm -rf ~'"'"''47```4849Экранирование совместимо с оболочками UNIX и с [`split()`](https://python-all.ru/3.5/library/shlex.html#shlex.split):5051```python52>>> remote_command = split(remote_command)53>>> remote_command54['ssh', 'home', "ls -l 'somefile; rm -rf ~'"]55>>> command = split(remote_command[-1])56>>> command57['ls', '-l', 'somefile; rm -rf ~']58```5960Новое в версии 3.3.6162Модуль [`shlex`](https://python-all.ru/3.5/library/shlex.html#module-shlex) определяет следующий класс:6364#### `class shlex.shlex(instream=None, infile=None, posix=False)`6566Экземпляр [`shlex`](https://python-all.ru/3.5/library/shlex.html#shlex.shlex) или его подкласса является объектом лексического анализатора. Аргумент инициализации, если он указан, определяет источник символов. Это должен быть файло- или потокоподобный объект с методами [`read()`](https://python-all.ru/3.5/library/io.html#io.TextIOBase.read) и [`readline()`](https://python-all.ru/3.5/library/io.html#io.TextIOBase.readline), либо строка. Если аргумент не задан, ввод берётся из `sys.stdin`. Второй необязательный аргумент – строка имени файла, которая задаёт начальное значение атрибута [`infile`](https://python-all.ru/3.5/library/shlex.html#shlex.shlex.infile). Если аргумент *instream* опущен или равен `sys.stdin`, этот второй аргумент по умолчанию принимает значение "stdin". Аргумент *posix* определяет режим работы: когда *posix* не является истинным (по умолчанию), экземпляр [`shlex`](https://python-all.ru/3.5/library/shlex.html#shlex.shlex) работает в режиме совместимости. При работе в режиме POSIX [`shlex`](https://python-all.ru/3.5/library/shlex.html#shlex.shlex) старается максимально точно соблюдать правила синтаксического анализа оболочки POSIX.6768> **См. также**69>70> **Модуль [`configparser`](https://python-all.ru/3.5/library/configparser.html#module-configparser)**71>72> Синтаксический анализатор конфигурационных файлов, аналогичных файлам73>74> `.ini`75>76> в Windows.7778## 24.3.1. Объекты shlex7980Экземпляр [`shlex`](https://python-all.ru/3.5/library/shlex.html#shlex.shlex) имеет следующие методы:8182#### `shlex.get_token()`8384Возвращает токен. Если токены были помещены в стек с помощью [`push_token()`](https://python-all.ru/3.5/library/shlex.html#shlex.shlex.push_token), извлекает токен из стека. В противном случае читает один токен из входного потока. Если при чтении сразу встречается конец файла, возвращается [`eof`](https://python-all.ru/3.5/library/shlex.html#shlex.shlex.eof) (пустая строка (`''`) в не-POSIX режиме и `None` в режиме POSIX).8586#### `shlex.push_token(str)`8788Помещает аргумент в стек токенов.8990#### `shlex.read_token()`9192Читает сырой токен. Игнорирует стек возврата и не интерпретирует запросы источника. (Обычно это не является полезной точкой входа и документируется здесь только для полноты.)9394#### `shlex.sourcehook(filename)`9596Когда [`shlex`](https://python-all.ru/3.5/library/shlex.html#shlex.shlex) обнаруживает запрос источника (см. [`source`](https://python-all.ru/3.5/library/shlex.html#shlex.shlex.source) ниже), этому методу передаётся следующий токен в качестве аргумента, и ожидается, что он вернёт кортеж, состоящий из имени файла и открытого файлоподобного объекта.9798Обычно этот метод сначала удаляет кавычки из аргумента. Если результат – абсолютный путь, или нет активного предыдущего запроса источника, или предыдущий источник был потоком данных (например, `sys.stdin`), результат остаётся без изменений. В противном случае, если результат – относительный путь, к нему добавляется часть пути каталога файла, находящегося непосредственно перед ним в стеке включения источников (такое поведение аналогично тому, как препроцессор C обрабатывает `#include "file.h"`).99100Результат этих действий трактуется как имя файла и возвращается в качестве первого компонента кортежа, а к нему применяется [`open()`](https://python-all.ru/3.5/library/functions.html#open) для получения второго компонента. (Примечание: это обратный порядок аргументов при инициализации экземпляра!)101102Этот хук предоставляется, чтобы вы могли использовать его для реализации путей поиска по каталогам, добавления расширений файлов и других трюков с пространствами имён. Соответствующего хука «закрытия» нет, но экземпляр shlex вызовет метод [`close()`](https://python-all.ru/3.5/library/io.html#io.IOBase.close) входного потока источника, когда тот вернёт EOF.103104Для более явного управления стеком источников используйте методы [`push_source()`](https://python-all.ru/3.5/library/shlex.html#shlex.shlex.push_source) и [`pop_source()`](https://python-all.ru/3.5/library/shlex.html#shlex.shlex.pop_source).105106#### `shlex.push_source(newstream, newfile=None)`107108Помещает поток входного источника в стек ввода. Если указан аргумент filename, он будет доступен позже для использования в сообщениях об ошибках. Это тот же метод, который внутренне используется методом [`sourcehook()`](https://python-all.ru/3.5/library/shlex.html#shlex.shlex.sourcehook).109110#### `shlex.pop_source()`111112Извлекает последний помещённый входной источник из стека ввода. Это тот же метод, который используется внутри, когда лексер достигает EOF для помещённого в стек входного потока.113114#### `shlex.error_leader(infile=None, lineno=None)`115116Этот метод формирует префикс сообщения об ошибке в формате метки ошибок компилятора C в Unix; формат – `'"%s", line %d: '`, где `%s` заменяется на имя текущего исходного файла, а `%d` – на номер текущей строки ввода (необязательные аргументы позволяют переопределить эти значения).117118Это удобство предоставляется для того, чтобы побудить пользователей [`shlex`](https://python-all.ru/3.5/library/shlex.html#module-shlex) генерировать сообщения об ошибках в стандартном, анализируемом формате, который понимают Emacs и другие инструменты Unix.119120Экземпляры подклассов [`shlex`](https://python-all.ru/3.5/library/shlex.html#shlex.shlex) имеют несколько открытых переменных экземпляра, которые либо управляют лексическим анализом, либо могут использоваться для отладки:121122#### `shlex.commenters`123124Строка символов, которые распознаются как начало комментария. Все символы от начала комментария до конца строки игнорируются. По умолчанию включает только `'#'`.125126#### `shlex.wordchars`127128Строка символов, которые будут накапливаться в составные токены. По умолчанию включает все буквы и цифры ASCII и символ подчёркивания.129130#### `shlex.whitespace`131132Символы, которые считаются пробельными и пропускаются. Пробельные символы разделяют токены. По умолчанию включает пробел, табуляцию, перевод строки и возврат каретки.133134#### `shlex.escape`135136Символы, которые будут считаться экранирующими. Это используется только в режиме POSIX и по умолчанию включает только `'\'`.137138#### `shlex.quotes`139140Символы, которые будут считаться строковыми кавычками. Токен накапливается до тех пор, пока не встретится та же самая кавычка (то есть разные типы кавычек защищают друг друга, как в оболочке). По умолчанию включает ASCII одинарные и двойные кавычки.141142#### `shlex.escapedquotes`143144Символы в [`quotes`](https://python-all.ru/3.5/library/shlex.html#shlex.shlex.quotes), которые будут интерпретировать экранирующие символы, определённые в [`escape`](https://python-all.ru/3.5/library/shlex.html#shlex.shlex.escape). Это используется только в режиме POSIX и по умолчанию включает только `'"'`.145146#### `shlex.whitespace_split`147148Если `True`, токены будут разделяться только по пробельным символам. Это полезно, например, для разбора командных строк с помощью [`shlex`](https://python-all.ru/3.5/library/shlex.html#shlex.shlex), получая токены аналогично аргументам оболочки.149150#### `shlex.infile`151152Имя текущего входного файла, установленное при создании экземпляра класса или помещённое в стек последующими запросами источников. Может быть полезно просмотреть его при формировании сообщений об ошибках.153154#### `shlex.instream`155156Входной поток, из которого данный экземпляр [`shlex`](https://python-all.ru/3.5/library/shlex.html#shlex.shlex) читает символы.157158#### `shlex.source`159160По умолчанию этот атрибут равен `None`. Если присвоить ему строку, эта строка будет распознаваться как запрос включения на лексическом уровне, аналогично ключевому слову `source` в различных оболочках. То есть следующий непосредственно токен будет открыт как имя файла, и ввод будет поступать из этого потока до достижения конца файла; после этого будет вызван метод [`close()`](https://python-all.ru/3.5/library/io.html#io.IOBase.close) этого потока, и источником ввода снова станет исходный входной поток. Запросы источника могут быть вложенными на любое количество уровней.161162#### `shlex.debug`163164Если этот атрибут является числовым и равен `1` или больше, экземпляр [`shlex`](https://python-all.ru/3.5/library/shlex.html#shlex.shlex) будет выводить подробную информацию о своих действиях. Если потребуется этим воспользоваться, можно изучить исходный код модуля, чтобы узнать подробности.165166#### `shlex.lineno`167168Номер строки в исходном файле (количество встреченных символов новой строки плюс один).169170#### `shlex.token`171172Буфер токенов. Его может быть полезно проверить при перехвате исключений.173174#### `shlex.eof`175176Токен, используемый для определения конца файла. В не-POSIX-режиме он устанавливается в пустую строку (`''`), а в POSIX-режиме – в `None`.177178## 24.3.2. Правила синтаксического анализа179180При работе в не-POSIX режиме [`shlex`](https://python-all.ru/3.5/library/shlex.html#shlex.shlex) будет следовать следующим правилам.181182- Символы кавычек не распознаются внутри слов (`Do"Not"Separate` разбирается как одно слово `Do"Not"Separate`);183- Символы экранирования не распознаются;184- Заключение символов в кавычки сохраняет буквальное значение всех символов внутри кавычек;185- Закрывающие кавычки разделяют слова (`"Do"Separate` разбирается как `"Do"` и `Separate`);186- Если значение [`whitespace_split`](https://python-all.ru/3.5/library/shlex.html#shlex.shlex.whitespace_split) равно `False`, любой символ, не объявленный как символ слова, пробел или кавычка, будет возвращён как односимвольный токен. Если оно равно `True`, [`shlex`](https://python-all.ru/3.5/library/shlex.html#shlex.shlex) будет разделять слова только по пробельным символам;187- EOF обозначается пустой строкой (`''`);188- Невозможно разобрать пустые строки, даже если они в кавычках.189190При работе в POSIX режиме [`shlex`](https://python-all.ru/3.5/library/shlex.html#shlex.shlex) будет следовать следующим правилам разбора.191192- Кавычки удаляются и не разделяют слова (`"Do"Not"Separate"` разбирается как одно слово `DoNotSeparate`);193- Неэкранированные (не в кавычках) escape-символы (например, `'\'`) сохраняют буквальное значение следующего за ними символа;194- Заключение символов в кавычки, не входящие в [`escapedquotes`](https://python-all.ru/3.5/library/shlex.html#shlex.shlex.escapedquotes) (например, `"'"`), сохраняет буквальное значение всех символов внутри кавычек;195- Заключение символов в кавычки, которые являются частью [`escapedquotes`](https://python-all.ru/3.5/library/shlex.html#shlex.shlex.escapedquotes) (например, `'"'`), сохраняет буквальное значение всех символов внутри кавычек, за исключением символов, упомянутых в [`escape`](https://python-all.ru/3.5/library/shlex.html#shlex.shlex.escape). Escape-символы сохраняют своё особое значение только в том случае, если за ними следует используемая кавычка или сам escape-символ. В противном случае escape-символ считается обычным символом.196- EOF обозначается значением [`None`](https://python-all.ru/3.5/library/constants.html#None);197- Пустые строки в кавычках (`''`) допускаются.198