Python Argparse:原始字符串输入

10

如果这个问题之前已经被问过,我很抱歉,但我确实搜索了一下,所有的结果似乎都是关于python中原始字符串的一般性讨论而不涉及argparse。

无论如何,我有一个代码,用户输入一个字符串然后这个字符串会被处理。然而,我的问题是我想让我的代码能够区分\n\\n,以便用户可以控制是否在输出中得到一个换行或者\n(分别)。

这本身相当简单,我可以让逻辑工作来检查字符串等。但是,argparse似乎不会保留输入字符串的原始状态。所以,如果我写:Here is a list:\nItem 1,它会被解析为Here is a list:\\nItem 1。由于在输入字符串中用\n替换\\n时解析出完全相同的内容,因此无法区分两者之间的差异。

我可以包含一个修补程序(例如,我可以让用户输入$\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 ) )

4
你需要区分由Python处理和由shell处理的内容。argparse仅能解析传递给Python进程的命令行参数,但它无法修改这些参数被shell如何处理。而且,在那里可能会发生一些转义,例如,即使在提示符中键入相同的字符,python -c "import sys; print sys.argv" My\nMagic\nString 在Windows的cmd.exebash中打印出不同的值。 - Łukasz Rogalski
答案与argparse无关。 - zondo
好的,那么你的意思是argparse正在按照我的预期工作,但终端程序出现了问题(即我已经输入了“\n”,但它告诉argparse是“\n”)?还是我误解了你的意思? - Steve
3个回答

4
这里是解决您问题的可能方案:
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确实是危险的


很遗憾,似乎这并不起作用。我认为@Lukasz-rogalski可能是正确的(如果我理解他的话),实际上问题出在终端而不是argparse :( - Steve
@Steve 【请尝试进一步阐述,因为显然我在发布之前已经测试了我的答案】(http://screencast.com/t/JoTkoZgt0C) - BPL
1
@BLP 抱歉,我表达不够清楚,我的意思并不是说它不起作用,而是当我使用它时,没有得到我想要的结果。我认为Lukasz已经确定问题出在终端方面。也就是说,如果我在终端中写入\\n(进行解析),那么它传递给解析器的实际上是\n;因此,在Python方面无法做任何事情。我认为这是终端自动忽略了额外反斜杠的情况。因此,看起来我需要在终端中使用\\\n才能使其传递给解析器\\n - Steve
@Steve,你的问题是“有没有办法确保由argparse解析的字符串是原始的?(即,如果我输入\n,则解析为\n而不是\n)”,我认为我的答案给了你一个可能的解决方案。但现在你说你没有得到你想要的结果...我不会因为你在SO上很有礼貌并且是新手而对你的问题进行负评。不过,我有一个建议,下次你要更加精确,否则有些人可能会生气的。欢迎来到SO。 - BPL
1
@BLP,对此我很抱歉,但我要为自己辩护,因为我认为问题就在那里。我正在将一个字符串输入到终端中,当经过argparse转换后,我查看该字符串时发现它被修改了(即\\n\n都变成了\n)。因此,我假设这是argparse无法解析原始字符串的情况(只有在Lukasz评论之后才意识到终端本身可以/会更改输入)。所以我尽力提出了当时最好的问题。很抱歉问题最终反映了我认为存在的问题而不是潜在的问题。无论如何,谢谢你的欢迎 :) - Steve

2

如评论中所述,argparsesys.argv 一起使用,后者是由 shell 和 Python 解释器生成的列表。

使用简单的 argv 回显脚本:

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

我在bash shell中遇到了以下问题:

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 ']

argparseargv 视为字符串列表。默认情况下,它不会对这些字符串进行任何操作,至少不会使用默认的 None type 参数。


2
如@hpaulj所指出的那样,你的问题源于shell和sys.argv的工作方式。你的选择是处理获取到的带转义字符的字符串。

参考SO上的这个答案:Process escape sequences in a string in Python。 基本上,使用string_escapeunicode_escape处理字符串。 这比手动处理字符串要好。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接