Python:如何在 optparse 中选择需要的选项?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4407539/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 15:36:15  来源:igfitidea点击:

Python: How to make an option to be required in optparse?

pythoncommand-linecommand-line-arguments

提问by Hyman

I've read this http://docs.python.org/release/2.6.2/library/optparse.html

我读过这个http://docs.python.org/release/2.6.2/library/optparse.html

But I'm not so clear how to make an option to be required in optparse?

但是我不太清楚如何在 optparse 中选择需要的选项?

I've tried to set "required=1" but I got an error:

我尝试设置“required=1”,但出现错误:

invalid keyword arguments: required

无效的关键字参数:必需

I want to make my script require --fileoption to be input by users. I know that the actionkeyword gives you error when you don't supply value to --filewhose action="store_true".

我想让我的脚本需要--file用户输入的选项。我知道action当您不向--filewho提供值时,关键字会给您错误action="store_true"

回答by user225312

You can implement a required option easily.

您可以轻松实现所需的选项。

parser = OptionParser(usage='usage: %prog [options] arguments')
parser.add_option('-f', '--file', 
                        dest='filename',
                        help='foo help')
(options, args) = parser.parse_args()
if not options.filename:   # if filename is not given
    parser.error('Filename not given')

回答by Fausto Luiz Santin

On the help message of each required variable Im writting a '[REQUIRED]' string at the beggining, to tag it to be parsed later, then I can simply use this function to wrap it around:

在每个必需变量的帮助消息上,我在开始时写了一个 '[REQUIRED]' 字符串,标记它以便稍后解析,然后我可以简单地使用这个函数来包装它:

def checkRequiredArguments(opts, parser):
    missing_options = []
    for option in parser.option_list:
        if re.match(r'^\[REQUIRED\]', option.help) and eval('opts.' + option.dest) == None:
            missing_options.extend(option._long_opts)
    if len(missing_options) > 0:
        parser.error('Missing REQUIRED parameters: ' + str(missing_options))

parser = OptionParser()
parser.add_option("-s", "--start-date", help="[REQUIRED] Start date")
parser.add_option("-e", "--end-date", dest="endDate", help="[REQUIRED] End date")
(opts, args) = parser.parse_args(['-s', 'some-date'])
checkRequiredArguments(opts, parser)

回答by vvladymyrov

I'm forced to use python 2.6 for our solution so I'm stick to optparse module. Here is solution I found to check for required options that works without specifying second time list of required options. Thus when you add new option you don't have to add it's name into the list of options to check.

我被迫使用 python 2.6 作为我们的解决方案,所以我坚持使用 optparse 模块。这是我发现的解决方案,用于检查所需选项,无需指定第二次所需选项列表即可工作。因此,当您添加新选项时,您不必将其名称添加到要检查的选项列表中。

My criteria for required option - option value should be not None and this options doesn't have default (user didn't specified add_option(default="...",...).

我对必需选项的标准 - 选项值不应为 None 并且此选项没有默认值(用户未指定 add_option(default="...",...)。

def parse_cli():
    """parse and check command line options, shows help message
    @return: dict - options key/value
    """
    import __main__
    parser = OptionParser(description=__main__.__doc__)
    parser.add_option("-d", "--days", dest="days",
                      help="Number of days to process")
    parser.add_option("-p", "--period", dest="period_length",default="2",
              help="number or hours per iteration, default value=%default hours")    
    (options, args) = parser.parse_args()

    """get dictionary of options' default values. 
       in this example: { 'period_length': '2','days': None}"""
    defaults = vars(parser.get_default_values())
    optionsdict = vars(options)

    all_none = False        
    for k,v in optionsdict.items():
        if v is None and defaults.get(k) is None:
            all_none = True


    if all_none:
        parser.print_help()
        sys.exit()
    return optionsdict

回答by arp

I'm also stuck on python 2.6 (pining for python2.7 and argparse, which not only has required arguments, but lets me specify that one of a set must be supplied); my approach requires a second pass, but lets me prompt for missing arguments unless running in batch mode:

我也被困在 python 2.6(为 python2.7 和 argparse 固定,它不仅有必需的参数,而且让我指定必须提供一组);我的方法需要第二遍,但让我提示缺少参数,除非在批处理模式下运行:

# from myscript
import helpers
import globalconfig 
parser = optparse.OptionParser(usage=myheader,epilog=myfooter)
parser.add_option("-L","--last",
                  action="store",dest="last_name",default="",
                  help="User's last (family) name; prompted for if not supplied"
                 )
parser.add_option("-y","--yes",
                  action="store_true",dest="batch_flag",default=False,
                  help="don't prompt to confirm actions (batch mode)"
                  )
[...]
(options, args) = parser.parse_args()
globalconfig.batchmode = options.batch_flag
[...]
last = prompt_if_empty(options.last_name,
        "Last name (can supply with \"-L\" or \"--last\" option):")


# from helpers.py
def prompt_if_empty(variable,promptstring):
    if not variable:
        if globalconfig.batchmode:
            raise Exception('Required variable missing.')
        print "%s" %promptstring
        variable = raw_input(globalconfig.prompt)
    return variable

(I'm thinking of making my own parser class that has common options for global configs baked in.)

(我正在考虑制作我自己的解析器类,该类具有用于全局配置的通用选项。)

Another answer to this question cited parser.error, which I was unfamiliar with when I wrote the code, but might have been a better choice.

这个问题的另一个答案引用了 parser.error,我在编写代码时不熟悉它,但可能是更好的选择。

回答by PatriceG

As the optparse module is deprecated since version 2.7, you will probably find some more up to date examples here: Dead simple argparse example wanted: 1 argument, 3 results

由于 optparse 模块自 2.7 版起已弃用,您可能会在此处找到更多最新示例:Dead simple argparse example Want: 1 argument, 3 results

回答by Matt Pitkin

The current answer with the most voteswould not work if, for example, the argument were an integer or float for which zero is a valid input. In these cases it would say that there is an error. An alternative (to add to the several others here) would be to do e.g.

例如,如果参数是整数或浮点数,而零是有效输入,则当前获得最多选票的答案将不起作用。在这些情况下,它会说有错误。另一种选择(在这里添加其他几个)是做例如

parser = OptionParser(usage='usage: %prog [options] arguments')
parser.add_option('-f', '--file', dest='filename')
(options, args) = parser.parse_args()
if 'filename' not in options.__dict__:
  parser.error('Filename not given')

回答by Serge M.

Since if not xdoesn't work for some(negative,zero) parameters,

由于if not x不适用于某些(负,零)参数,

and to prevent lots of if tests, i preferr something like this:

为了防止大量的 if 测试,我更喜欢这样的事情:

required="host username password".split()

parser = OptionParser()
parser.add_option("-H", '--host', dest='host')
parser.add_option("-U", '--user', dest='username')
parser.add_option("-P", '--pass', dest='password')
parser.add_option("-s", '--ssl',  dest='ssl',help="optional usage of ssl")

(options, args) = parser.parse_args()

for r in required:
    if options.__dict__[r] is None:
        parser.error("parameter %s required"%r)

回答by kenorb

There are at least two methods of implementing required options with optparse. As mentioned in the docs page, optparsedoesn't prevent you from implementing required options, but doesn't give you much help at it either. Find below the examples found in files distributed with the source.

至少有两种方法可以使用optparse. 正如文档页面中所述,optparse不会阻止您实现所需的选项,但也不会为您提供太多帮助。在下面找到与源代码一起分发的文件中的示例。

Although please note that optparsemoduleis deprecated since version 2.7 and will not be developed further. You should use argparsemoduleinstead.

但请注意,optparse模块自 2.7 版起已弃用,不会进一步开发。您应该改用argparse模块



Version 1: Add a method to OptionParser which applications must call after parsing arguments:

版本 1:向 OptionParser 添加一个方法,应用程序在解析参数后必须调用该方法:

import optparse

class OptionParser (optparse.OptionParser):

    def check_required (self, opt):
      option = self.get_option(opt)

      # Assumes the option's 'default' is set to None!
      if getattr(self.values, option.dest) is None:
          self.error("%s option not supplied" % option)


parser = OptionParser()
parser.add_option("-v", action="count", dest="verbose")
parser.add_option("-f", "--file", default=None)
(options, args) = parser.parse_args()

print "verbose:", options.verbose
print "file:", options.file
parser.check_required("-f")

Source: docs/lib/required_1.txt

来源: docs/lib/required_1.txt



Version 2: Extend Option and add a required attribute; extend OptionParser to ensure that required options are present after parsing:

版本 2:扩展选项并添加一个必需的属性;扩展 OptionParser 以确保解析后存在所需的选项:

import optparse

class Option (optparse.Option):
    ATTRS = optparse.Option.ATTRS + ['required']

    def _check_required (self):
        if self.required and not self.takes_value():
            raise OptionError(
                "required flag set for option that doesn't take a value",
                 self)

    # Make sure _check_required() is called from the constructor!
    CHECK_METHODS = optparse.Option.CHECK_METHODS + [_check_required]

    def process (self, opt, value, values, parser):
        optparse.Option.process(self, opt, value, values, parser)
        parser.option_seen[self] = 1


class OptionParser (optparse.OptionParser):

    def _init_parsing_state (self):
        optparse.OptionParser._init_parsing_state(self)
        self.option_seen = {}

    def check_values (self, values, args):
        for option in self.option_list:
            if (isinstance(option, Option) and
                option.required and
                not self.option_seen.has_key(option)):
                self.error("%s not supplied" % option)
        return (values, args)


parser = OptionParser(option_list=[
    Option("-v", action="count", dest="verbose"),
    Option("-f", "--file", required=1)])
(options, args) = parser.parse_args()

print "verbose:", options.verbose
print "file:", options.file

Source: docs/lib/required_2.txt

来源: docs/lib/required_2.txt

回答by Alex

I would use argparse library that has this functionality embedded:

我会使用嵌入了此功能的 argparse 库:

PARSER.add_argument("-n", "--namespace", dest="namespace", required=True,
              help="The path within the repo to the data base")

argparse reference

argparse 引用