Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中解析空选项_Python_Optparse_Optionparser - Fatal编程技术网

在Python中解析空选项

在Python中解析空选项,python,optparse,optionparser,Python,Optparse,Optionparser,我有一个应用程序,允许您将事件数据发送到自定义脚本。您只需布置命令行参数,并指定哪些事件数据与哪些参数一起使用。问题是这里没有真正的灵活性。您绘制的每个选项都将被使用,但并非每个选项都必须有数据。因此,当应用程序构建要发送到脚本的字符串时,一些参数为空,python的OptionParser错误为“error:--someargument选项需要一个参数” 因为有超过200个数据点,所以我不能编写单独的脚本来处理每个可能的参数组合(需要2^200个脚本)。python的optionparser中

我有一个应用程序,允许您将事件数据发送到自定义脚本。您只需布置命令行参数,并指定哪些事件数据与哪些参数一起使用。问题是这里没有真正的灵活性。您绘制的每个选项都将被使用,但并非每个选项都必须有数据。因此,当应用程序构建要发送到脚本的字符串时,一些参数为空,python的OptionParser错误为“error:--someargument选项需要一个参数”


因为有超过200个数据点,所以我不能编写单独的脚本来处理每个可能的参数组合(需要2^200个脚本)。python的optionparser中有没有处理空参数的方法?

是的,添加选项时有一个参数可以处理空参数:

from optparse import OptionParser
parser = OptionParser()
parser.add_option("--SomeData",action="store", dest="TheData", default='')

为默认参数指定您希望选项具有的值,但可以选择具有参数。

我认为
optpasse
无法做到这一点。是一个不同的(非标准)模块,可以在选项具有可选值的地方使用


使用
optpasse
时,您必须指定包含其值的选项,或者同时忽略这两个选项。

对不起,我的第一个答案误解了这个问题。您可以在定义选项时使用回调操作类型,为命令行标志提供可选参数。使用以下函数作为回调函数(您可能希望根据自己的需要进行调整),并为每个可选择接收参数的标志配置该函数:

import optparse

def optional_arg(arg_default):
    def func(option,opt_str,value,parser):
        if parser.rargs and not parser.rargs[0].startswith('-'):
            val=parser.rargs[0]
            parser.rargs.pop(0)
        else:
            val=arg_default
        setattr(parser.values,option.dest,val)
    return func

def main(args):
    parser=optparse.OptionParser()
    parser.add_option('--foo',action='callback',callback=optional_arg('empty'),dest='foo')
    parser.add_option('--file',action='store_true',default=False)
    return parser.parse_args(args)

if __name__=='__main__':
    import sys
    print main(sys.argv)


从命令行运行时,您将看到:

# python parser.py
(<Values at 0x8e42d8: {'foo': None, 'file': False}>, [])

# python parser.py --foo
(<Values at 0x8e42d8: {'foo': 'empty', 'file': False}>, [])

# python parser.py --foo bar
(<Values at 0x8e42d8: {'foo': 'bar', 'file': False}>, [])
#python parser.py
(, [])
#python parser.py--foo
(, [])
#python parser.py——foo-bar
(, [])

optpasse已经允许您将空字符串作为选项参数传递。因此,如果可能,将空字符串视为“无值”。对于长选项,请执行以下任一操作:

my_script --opt=   --anotheroption
my_script --opt='' --anotheroption
my_script --opt="" --anotheroption
my_script --opt '' --anotheroption
my_script --opt "" --anotheroption
对于短样式选项,可以使用以下任一选项:

my_script -o '' --anotheroption
my_script -o "" --anotheroption

警告:这已经在Linux下测试过了,在其他Unixlike系统下也应该可以使用;Windows以不同的方式处理命令行引用,可能不接受上面列出的所有变体。

Mark Roddy的解决方案可以工作,但它需要在运行时修改解析器对象的属性,并且不支持-或--以外的其他选项格式。 一个稍微不太复杂的解决方案是在运行optpass之前修改sys.argv数组,并在不需要参数的开关后插入一个空字符串(“”)。 此方法的唯一限制是,您的选项默认为可预测的值,而不是插入sys.argv的值(我在下面的示例中选择了“无”,但这并不重要)

下面的代码创建一个示例解析器和一组选项,从解析器中提取一个允许的开关数组(使用一点实例变量magic),然后遍历sys.argv,每次它找到一个 allowed开关,它检查是否在没有任何参数的情况下给出它。如果开关后没有参数,则将在命令上插入空字符串 线路。更改sys.argv后,将调用解析器,您可以检查值为“”的选项,并相应地执行操作

#Instantiate the parser, and add some options; set the options' default values to None, or something predictable that
#can be checked later.
PARSER_DEFAULTVAL = None
parser = OptionParser(usage="%prog -[MODE] INPUT [options]")
#This method doesn't work if interspersed switches and arguments are allowed.
parser.allow_interspersed_args = False
parser.add_option("-d", "--delete", action="store", type="string", dest="to_delete", default=PARSER_DEFAULTVAL)
parser.add_option("-a", "--add", action="store", type="string", dest="to_add", default=PARSER_DEFAULTVAL)

#Build a list of allowed switches, in this case ['-d', '--delete', '-a', '--add'] so that you can check if something
#found on sys.argv is indeed a valid switch. This is trivial to make by hand in a short example, but if a program has
#a lot of options, or if you want an idiot-proof way of getting all added options without modifying a list yourself,
#this way is durable. If you are using OptionGroups, simply run the loop below with each group's option_list field.
allowed_switches = []
for opt in parser.option_list:
    #Add the short (-a) and long (--add) form of each switch to the list.
    allowed_switches.extend(opt._short_opts + opt._long_opts)

#Insert empty-string values into sys.argv whenever a switch without arguments is found.
for a in range(len(sys.argv)):
    arg = sys.argv[a]
    #Check if the sys.argv value is a switch
    if arg in allowed_switches:
        #Check if it doesn't have an accompanying argument (i.e. if it is followed by another switch, or if it is last
        #on the command line)
        if a == len(sys.argv) - 1 or argv[a + 1] in allowed_switches:
            sys.argv.insert(a + 1, "")

options, args = parser.parse_args()

#If the option is present (i.e. wasn't set to the default value)
if not (options.to_delete == PARSER_DEFAULTVAL):
    if options.droptables_ids_csv == "":
        #The switch was not used with any arguments.
        ...
    else:
        #The switch had arguments.
        ...

检查
cp
命令是否理解,例如
--backup=simple
但不理解
--backup simple
,我回答了如下问题:

import sys
from optparse import OptionParser

def add_optval_option(pog, *args, **kwargs):
    if 'empty' in kwargs:
        empty_val = kwargs.pop('empty')
        for i in range(1, len(sys.argv)):
            a = sys.argv[i]
            if a in args:
                sys.argv.insert(i+1, empty_val)
                break
    pog.add_option(*args, **kwargs)

def main(args):
    parser = OptionParser()
    add_optval_option(parser,
                      '--foo', '-f',
                      default='MISSING',
                      empty='EMPTY',
                      help='"EMPTY" if given without a value. Note: '
                      '--foo=VALUE will work; --foo VALUE will *not*!')
    o, a = parser.parse_args(args)
    print 'Options:'
    print '  --foo/-f:', o.foo
    if a[1:]:
        print 'Positional arguments:'
        for arg in a[1:]:
            print ' ', arg
    else:
        print 'No positional arguments'

if __name__=='__main__':
    import sys
    main(sys.argv)

自我宣传:这是我的
thebops
包的
opo
模块的一部分…;-)

我使用的是默认选项,但只有在命令行中未指定--SomeData时才使用。如果您这样做:--SomeData--SomeMoreData等等,那么--SomeData错误,因为它没有传递值。@directedition抱歉,我误解了您的问题。发布另一个答案,并提供一个应该适合您的解决方案。此变体的问题是
--for=bar
将不起作用:
parser.py:error:--foo选项不接受值
当然这是可行的,但它与简单地使用
my_脚本--opt
不同。