Python optparse和参数中的空格

7
当使用optparse时,我想要获取选项后面的整个字符串,但是我只能获取到第一个空格之前的部分。
例如:
python myprog.py --executable python someOtherProg.py

我在“可执行文件”中得到的只是“python”。

使用optparse解析这样的行是否可能,还是必须使用argparse来完成?

€:我已经尝试将其括在“s中。但是在进一步挖掘代码后,我发现子进程调用无法处理该参数。

包含命令行的字符串被塞入列表“args”中。

args = [self.getExecutable()] + self.getArgs().split()

这就像是

"[python D:\\\workspace\\\myprog\\\src\\\myprog.py]"

这导致了系统找不到文件的异常。当我使用时,会出现这种情况。
args[0]

它可以工作,但我失去了对可执行文件的参数。

如果subprocess模块没有首先获取字符串,则会从列表中构建cmdline,因此我目前无法解释该行为。

5个回答

13

你可以用引号将它们包裹起来,这样它们就可以与现有的代码一起使用。

python myprog.py --executable "python someOtherProg.py"

是否可以使用optparse解析这些行,或者必须使用argparse来完成?

我不知道如何使用optparse实现,因为我没有真正使用过optparse

不过,我可以帮助你使用argparse。以下是一个快速示例:

#!/usr/bin/python
import argparse, sys

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description = 'Demonstration of Argparse.')
    parser.add_argument('-e', '--executable', nargs = '+', help = 'List of executables')
    args = parser.parse_args(sys.argv[1:])
    print args.executable

使用方法:

manoj@maruti:~$ python myprog.py --executable python someOtherProg.py
['python', 'someOtherProg.py']

我还建议从optparse切换到argparse。因为optparse已经自Python2.7版本以后被弃用


6
我找到了另一个好的替代品shlex——一种用于简单shell语法的词法分析器类。

源链接:如何使用正则表达式解析命令行?

>>> import shlex
>>> shlex.split('"param 1" param2 "param 3"')
['param 1', 'param2', 'param 3']
>>> shlex.split('"param 1" param2 "param 3"')
Traceback (most recent call last):
    [...]
ValueError: No closing quotation
>>> shlex.split('"param 1" param2 "param 3\\""')
['param 1', 'param2', 'param 3"']

4
如果你知道参数标识后面会有多少个单词,你可以修改在optparse中创建--executable选项的方式以正确处理这种情况:
不是在选项标识后只获取一个单词,而是设置optparse解析器去查找两个或更多单词。
from optparse import OptionParser
parser = OptionParser()

parser.add_option("-f", "--file", action="store", dest="filename",
                       help="File to be processed.", metavar="FILE")
parser.add_option("-e", "--executable", action="store", dest="my_exe",
                       help="Command to be executed", metavar="EXE",
                       nargs=2)

在这段代码中,-f--file选项只需要一个单词,并将其作为字符串(默认值)存储在filename变量中。
相比之下,-e--executable选项由于nargs=2选项而期望两个单词。这将导致在-e--executable标志后面找到的两个单词被存储为字符串列表my_exe
查看:http://docs.python.org/library/optparse.html了解更多关于optparse的信息,并记住它已经在2.7版本中被弃用,推荐使用argparse

4
你看到的行为源于你的shell而非Python解析命令行并将其分解为sys.argv的单词。Python是通过exec()由shell启动的,argv已经被填充了。

大多数shell会在空格处拆分argv项目,除非你使用引号或转义字符告诉它们不这样做。

引号的作用如上所述。

在许多shell中,你可以这样做:

python myprog.py --executable python\ someOtherProg.py

反斜杠可以转义后面的空格而不需要使用引号。

准备好惊叹吧:在Python 3.5下,sys.argv会取消转义空格!在C语言中,我们有silly python someargv[1]="python"argv[2]="some"silly "python some"argv[1]="python some"。而silly python\ someargv[1]="python some"。但是在Python 3.5中,我们有silly.py python someargv[1]="python"argv[2]="some"silly.py "python some"argv[1]="python some"。而silly.py python\ someargv[1]="python\\""some"。太神奇了! - Urhixidur

1

如果您无法升级到argparse,请使用以下列表来完成答案。

Optparse无法处理这些情况(多个字符串)。 您只能使用nargs指定特定数量的变量,但没有像“一个或多个”这样的东西。 您需要进行修改使用不同的库(例如argparse或其他库)。


你能告诉我如何使用argparse处理它吗?不使用sys.argv。我猜argparse也没有像parse_string这样的功能,而是像parse_args一样,例如解析包含空格的字符串,如"one or more" - shahjapan
argparse 有限,我对它的经验不多 :-( - lzap
请看我提供的另一种解决方案,它可以使用 shlex 库独立地与 argparseoptparse 一起使用。 - shahjapan

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