【问题标题】:Adding suboptions using optparse in Jython在 Jython 中使用 optparse 添加子选项
【发布时间】:2014-01-21 23:05:07
【问题描述】:

我正在使用 optparse 向 Jython 脚本添加选项。他们就像

$script.py -clear
$script.py -start
$script.py -stop 

等等,现在我的问题是如何将子选项添加到任何特定选项,例如

$script.py -start -name <name> -type <type>,

因为可能有很多选项,我无法通过捕获单个级别的所有选项来验证或提供帮助。我发现对于一些脚本有类似的选项

$script.py -start --help

-> 这将只给出可以给父 'start' 选项的选项。所以请帮助我如何实现这一目标

谢谢, 查克里

【问题讨论】:

    标签: java python jython optparse


    【解决方案1】:

    无法添加“子”选项。通常,帮助选项由 $script.py --help start 之类的东西完成 - 其中 start 只是一个字符串选项,您可以读取并显示相应的信息。

    【讨论】:

      【解决方案2】:

      我最近遇到了同样的问题。对我有用的解决方案如下:

      • 按照惯例,使用第一个参数来表示你想要的命令 执行(这将是你的startclearstop

      • 通过sys.argv[1] 获取此命令(我知道这很难看 解决方法)

      • 创建多个optparse.OptionParser()(每个命令一个)

      • 仅调用相应OptionParserparse_args() 方法

      • 如果命令无效或丢失,请创建另一个选项解析器以显示用法

      这是一个示例代码:

      # parse.py
      
      import sys
      import optparse
      
      def parse_my_command_line():
      
          opt_parser = {}
          opt_parser['start'] = optparse.OptionParser()
          opt_parser['clear'] = optparse.OptionParser()
          opt_parser['stop']  = optparse.OptionParser()
      
          # Start
          opt_parser['start'].usage = 'Help for the START command'
          opt_parser['start'].add_option('--name', default = None, type = 'str',
              help = 'help for --name option', metavar = '<name>')
          opt_parser['start'].add_option('--type', default = None, type = 'str',
              help = 'help for --type option', metavar = '<type>')
      
          # Clear
          opt_parser['clear'].usage = 'Help for the CLEAR command'
          opt_parser['clear'].add_option('--foo', default = None, type = 'str',
              help = 'help for --foo option', metavar = '<foo>')
      
          # Stop
          opt_parser['stop'].usage = 'Help for the STOP command'
          opt_parser['stop'].add_option('--name', default = None, type = 'str',
              help = 'help for --name option', metavar = '<name>')
          opt_parser['stop'].add_option('--type', default = None, type = 'str',
              help = 'help for --type option', metavar = '<type>')
      
          # Get the command from sys.argv
          try:
              command = sys.argv[1]
          except IndexError:
              command = None
      
          # Get the appropriate option parser
          try:
              parser = opt_parser[command]
              # Done. Parse arguments and return.
              return parser.parse_args()
          except KeyError:
              # Invalid command. Create a parser to show default usage
              parser       = optparse.OptionParser()
              parser.usage  = '%prog [command] [options]\n\n'
              parser.usage += 'Description:\n'
              parser.usage += '  General help for %prog\n\n'
              parser.usage += 'Commands:\n'
              for cmd in ['start', 'clear', 'stop']:
                  parser.usage += '  %s\n' % cmd
                  parser.usage += '    %s\n\n' % opt_parser[cmd].usage
              parser.usage = parser.usage.strip()
              if command is None:
                  parser.error('command cannot be empty')
              else:
                  parser.error('invalid command: %s' % command)
      
      
      
      def main():
          options, args = parse_my_command_line()
          print 'Args    = %s' % args
          print 'Options = %s' % options
      
      if __name__ == '__main__':
          main()
      

      这里有一些结果:

      [usr@localhost ~]$ python parse.py
      Usage: parse.py [command] [options]
      
      Description:
        General help for parse.py
      
      Commands:
        start
          Help for the START command
      
        clear
          Help for the CLEAR command
      
        stop
          Help for the STOP command
      
      parse.py: error: command cannot be empty
      
      [usr@localhost ~]$ python parse.py start
      Args    = ['start']
      Options = {'type': None, 'name': None}
      
      [usr@localhost ~]$ python parse.py stop
      Args    = ['stop']
      Options = {'type': None, 'name': None}
      
      [usr@localhost ~]$ python parse.py clear
      Args    = ['clear']
      Options = {'foo': None}
      
      [usr@localhost ~]$ python parse.py start --help
      Usage: Help for the START command
      
      Options:
        -h, --help     show this help message and exit
        --name=<name>  help for --name option
        --type=<type>  help for --type option
      [usr@localhost ~]$ python parse.py stop -- help
      Args    = ['stop', 'help']
      Options = {'type': None, 'name': None}
      
      [usr@localhost ~]$ python parse.py clear --help
      Usage: Help for the CLEAR command
      
      Options:
        -h, --help   show this help message and exit
        --foo=<foo>  help for --foo option
      

      【讨论】:

      • 注意:自 python 2.7 版起,不鼓励使用 optparse。 optparse 模块已弃用,不会进一步开发; argparse 模块将继续开发。请参阅PEP 0389 了解更多信息。
      【解决方案3】:

      这正是 OptionParser 的设计初衷!

      考虑以下代码:

      import sys
      import os
      
      from optparse import OptionParser
      
      __all__ = []
      __version__ = 0.1
      __date__ = '2014-01-21'
      __updated__ = '2014-01-21'
      
      
      def main(argv=None):
          '''Command line options.'''
      
          program_name = os.path.basename(sys.argv[0])
          program_version = "v0.1"
          program_build_date = "%s" % __updated__
      
          program_version_string = '%%prog %s (%s)' % (program_version, program_build_date)
      
          program_longdesc = '''This will be displayed beneath your help information''' # optional - give further explanation about what the program does
          program_license = "Copyright 2014 Code Tester (Jython Dev Inc.)                                            \
                      Licensed under the Apache License 2.0\nhttp://www.apache.org/licenses/LICENSE-2.0"
      
          if argv is None:
              argv = sys.argv[1:]
          try:
              # setup option parser
              parser = OptionParser(version=program_version_string, epilog=program_longdesc, description=program_license)
              parser.add_option("-i", "--in", dest="infile", help="set input path [default: %default]", metavar="FILE")
              parser.add_option("-o", "--out", dest="outfile", help="set output path [default: %default]", metavar="FILE")
              parser.add_option("-d", "--debug", dest="modeDebug", action="store_true", help="Prints additional debug information")
              parser.add_option("-m", "--map", dest="listKVPs", action="append", help="Key value pair mappings (i.e. left=right)", metavar="KVP")
              parser.add_option("-r", "--role", dest="listProtectedRoles", action="append", help="Protected system roles to use (multiple allowed)", metavar="Role")
              parser.add_option("-u", "--user", dest="listProtectedUsers", action="append", help="Protected system users to be used (multiple allowed)", metavar="User")
      
              # set defaults
              parser.set_defaults(outfile="./out.txt", infile="./in.txt")
      
              # process options
              (opts, args) = parser.parse_args(argv)
      
              if opts.modeDebug:
                  print("Running in DEBUG mode")
              if opts.infile:
                  print("infile = %s" % opts.infile)
              if opts.outfile:
                  print("outfile = %s" % opts.outfile)
              if opts.listKVPs:
                  print("KVP's = %s" % opts.listKVPs)
              if opts.listProtectedRoles:
                  print("Protected Roles = %s" % opts.listProtectedRoles)
              if opts.listProtectedUsers:
                  print("Protected Users = %s" % opts.listProtectedUsers)
      
              '''
              Do something interesting with the parameters here!
              '''
      
      
          except Exception, e:
              indent = len(program_name) * " "
              sys.stderr.write(program_name + ": " + repr(e) + "\n")
              sys.stderr.write(indent + "  for help use --help")
              return 2
      
      
      if __name__ == "__main__":
          sys.exit(main())
      

      如果你使用 -h(或 --help)运行它,你会得到以下结果:

      Usage: OptParseExample.py [options]
      
      Copyright 2014 Code Tester (Jython Dev Inc.)
      Licensed under the Apache License 2.0
      http://www.apache.org/licenses/LICENSE-2.0
      
      Options:
        --version             show program's version number and exit
        -h, --help            show this help message and exit
        -i FILE, --in=FILE    set input path [default: ./in.txt]
        -o FILE, --out=FILE   set output path [default: ./out.txt]
        -d, --debug           Prints additional debug information
        -m KVP, --map=KVP     Key value pair mappings (i.e. left=right)
        -r Role, --role=Role  Protected system roles to use (multiple allowed)
        -u User, --user=User  Protected system users to be used (multiple allowed)
      
      This will be displayed beneath your help information
      

      现在,如果我们使用更多参数运行它,即:

      testScript.py -d -i input.txt -o output.txt -m jython=cool -r Admins -r DomainAdmins
      

      我们得到显示的输出:

      Running in DEBUG mode
      infile = input.txt
      outfile = output.txt
      KVP's = ['jython=cool']
      Protected Roles = ['Admins', 'DomainAdmins']
      

      注意几点:

      • 命令行中参数的顺序并不重要(只要参数提供了相关的标志)
      • 本例中的 -d 选项用作“store_true”参数,表示它是一个布尔标志
      • 其他参数都取附加值
      • 如果带值的参数可以接受多个值,则可以将其声明为列表(使用附加操作)
      • 处理完所有参数后,您仍然可以通过“args”变量获得任何其他命令行参数。

      更多信息请关注http://jython.org/docs/library/optparse.html

      【讨论】:

      • 注意 - 回应 shakaran(由于某种原因,我无法回复该评论!) - 我不确定 argparse 模块当前是否可用于 Jython。
      猜你喜欢
      • 2011-10-17
      • 1970-01-01
      • 1970-01-01
      • 2013-03-25
      • 2011-06-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多