Python Argparse: ввод необработанной строки

Извиняюсь, если об этом спрашивали раньше, я искал его, но все совпадения, похоже, касались необработанных строк python в целом, а не argparse.

В любом случае, у меня есть код, в котором пользователь вводит строку, а затем эта строка обрабатывается. Однако у меня есть проблема, так как я хочу, чтобы мой код мог различать \n и \\n, чтобы пользователь мог контролировать, получают ли они разрыв строки или \n в выводе (соответственно).

Это само по себе довольно просто, и я могу заставить работать логику для проверки строки и т. д. Однако argparse, похоже, не сохраняет исходную строку ввода. Итак, если бы я написал: Here is a list:\nItem 1, он будет проанализирован как Here is a list:\\nItem 1. Поскольку точно такая же вещь анализируется, если я заменю \n на \\n во входной строке, становится невозможно различать их.

Я мог бы включить bodge (например, я мог бы заставить пользователя ввести $\n, чтобы \n появилось в выводе, или просто \n для разрыва строки). Но это беспорядочно и усложняет использование кода.

Есть ли способ убедиться, что строка, анализируемая argparse, является необработанной? (То есть, если я ввожу \n, он анализирует \n, а не \\n)

Опять же, извините, если об этом спрашивали раньше, но я не смог найти ответ, и после более чем часа попыток найти ответ у меня закончились идеи (за исключением бреда). Заранее приветствую любую помощь.

Пример кода (извините, если это не работает, не знаю, как лучше сделать пример кода для argparse!):

import argparse

parser = argparse.ArgumentParser( description = 'Test.' )
parser.add_argument( 'text', action = 'store', type = str, help = 'The text to parse.' )

args = parser.parse_args( )

print( repr( args.text ) )

person Steve    schedule 24.08.2016    source источник
comment
Вам нужно разделить то, что обрабатывается Python, и то, что обрабатывается оболочкой. argparse может только анализировать аргументы командной строки, переданные процессу Python, но не может изменять способ обработки этих аргументов оболочкой. И какой-то побег может или может сейчас произойти там, например. python -c "import sys; print sys.argv" My\nMagic\nString печатает другое значение в cmd.exe Windows и другое значение в bash, даже если в приглашении мы набираем те же символы.   -  person Łukasz Rogalski    schedule 24.08.2016
comment
Возможный дубликат Как мне отменить экранирование строка с обратной косой чертой в python?   -  person zondo    schedule 24.08.2016
comment
Ответ не связан с argparse.   -  person zondo    schedule 24.08.2016
comment
Итак, вы имеете в виду, что argparse работает так, как я хочу, однако именно терминал вызывает проблемы (т.е. я набрал \n, но он сказал argparse \\n)? Или я вас неправильно понимаю?   -  person Steve    schedule 24.08.2016


Ответы (3)


Вот возможное решение вашей проблемы:

import argparse

parser = argparse.ArgumentParser(description='Test.')
parser.add_argument('text', action='store', type=str, help='The text to parse.')

args = parser.parse_args()

print '-' * 80
raw_text = eval('"' + args.text.replace('"', '\\"') + '"')
print raw_text
print '-' * 80
print args.text

Но имейте в виду, что eval действительно опасен.

person BPL    schedule 24.08.2016
comment
К сожалению, похоже, это не работает. Я думаю, что @Lukasz-rogalski может быть прав (если я правильно его понимаю), что на самом деле проблема заключается в терминале, а не в argparse :( - person Steve; 24.08.2016
comment
@BLP Извините, я плохо говорил там, я не хотел сказать, что это не работает, скорее, когда я его использовал, он не дал тех результатов, которые мне нужны. Я думаю, Лукаш определил, что проблема заключается в конечной стороне вещей. То есть, если я напишу \\n в терминале (для анализа), то, что он даст анализатору, на самом деле будет \n; так что ничего нельзя сделать на стороне python. Я думаю, что это случай, когда терминал автоматически игнорирует дополнительную обратную косую черту. Таким образом, похоже, что мне нужно использовать \\\n в терминале, чтобы он отдал парсеру \\n. - person Steve; 24.08.2016
comment
@Steve Ваш вопрос задан Is there a way to ensure the string being parsed by argparse is raw? (I.e. if I enter \n it parses \n and not \\n), я думаю, что мой ответ дал вам возможное решение. Но теперь вы говорите, что не получили желаемых результатов... Я не буду отрицать ваш вопрос, потому что вы вежливы и новичок в SO. Однако один совет: некоторые люди могут разозлиться, если в следующий раз вы не будете более точны ;). Добро пожаловать в СО - person BPL; 24.08.2016
comment
@BLP, извините за это, но в свою защиту, вопрос был в проблеме, как я ее видел. Я вводил строку в терминал, и когда я посмотрел на эту строку после прохождения argparse, она была изменена (т.е. и \\n, и \n стали \n). Таким образом, я предположил, что это был случай, когда argparse не анализирует необработанную строку (только понимая, что сам терминал может/изменяет входные данные после комментария Лукаша). Поэтому я задал лучший вопрос, который мог на тот момент. Мне жаль, что вопрос оказался более отражающим проблему, которую, как я думал, у меня была, а не основную проблему. Однако спасибо за прием :) - person Steve; 24.08.2016

Как отмечено в комментариях, argparse работает с sys.argv, списком, созданным оболочкой и интерпретатором Python.

С помощью простого эхо-скрипта argv:

0928:~/mypy$ cat echo_argv.py
import sys
print(sys.argv)

Я получаю (с оболочкой bash):

0929:~/mypy$ python echo_argv.py Here is a list:\nItem 1 
['echo_argv.py', 'Here', 'is', 'a', 'list:nItem', '1']
0931:~/mypy$ python echo_argv.py "Here is a list:\nItem 1 "
['echo_argv.py', 'Here is a list:\\nItem 1 ']
0931:~/mypy$ python echo_argv.py "Here is a list:\\nItem 1 "
['echo_argv.py', 'Here is a list:\\nItem 1 ']

argparse обрабатывает этот argv как список строк. Он ничего не делает с этими строками, по крайней мере, не с параметром по умолчанию None type.

person hpaulj    schedule 24.08.2016

Как указал @hpaulj, ваша проблема возникла из-за оболочки и из-за того, как работает sys.argv. Ваш вариант - обработать строку с помощью escape-символов, которые вы получили.

Взгляните на этот ответ на SO: Escape-последовательности обработки в строке в Питон . По сути, используйте string_escape или unicode_escape для обработки строки. Это лучше, чем вручную обрабатывать вашу строку.

person bizi    schedule 05.10.2017