Argument parsing in Python (required vs. optional)

倾然丶 夕夏残阳落幕 提交于 2019-12-24 04:36:28

问题


I'm currently working on a script that will be able to take multiple flags. I want it so that no matter what the last argument should be 'start|stop|status'.

#!/usr/bin/env python

from argparse import ArgumentParser


def argument_analysis():
    """
This will analyze arguments, and return the region as a string, the filter as a dictionary, and the command as a string.
    :return: region,filters,command
    """
    parser_options = ArgumentParser()
    parser_options.add_argument("-r", "--region", dest='region',
                                help="Filter by region.")
    parser_options.add_argument("-n", "--name", dest='name',
                                help="Filter by hostname.")
    parser_options.add_argument("-P", "--project", dest='project',
                                help="Filter by Project tag.")
    parser_options.add_argument("-U", "--usage", dest='usage',
                                help="Filter by Usage tag.")
    parser_options.add_argument("-i", "--instance_id", dest='instance_id',
                                help="Filter by instance_id.")
    parser_options.add_argument("-t", "--type", dest='type',
                                help="Filter by instance_size.")
    parser_options.add_argument("-p", "--ip", dest='internal_ip',
                                help="Filter by internal_ip")
    parser_options.add_argument("-c", "--command", dest='command',
                                help="stop/start, or check the status of instances.")
    parser_options.add_argument("-a", "--all", dest='all', default=False, action='store_true',
                                help="No filter, display status of all servers.")
    arguments = vars(parser_options.parse_args())
    return arguments


if __name__ == '__main__':
    print argument_analysis()

I want it so that ./argument_analysis_script.py will require a 'stop|start|status' at the end. I haven't had much luck getting help with the ARgumentParser(). If anybody has any suggestions it would be very helpful.

Thanks in advance for your time.

NOTE: I would like for the script to stop if [stop|start|restart|status] is not entered, and explain that [stop|start|restart|status] is required.

**UPDATE** **UPDATE** **UPDATE**

After doing some more digging, to be able to analyze/use command line options, and arguments, I stumbled upon OptionParser, which I avoided as docs.python.org states it's deprecated. Anyway, since that is the only thing that I could find to give me exactly what I wanted, here is an update of what I've got:

#!/usr/bin/env python

from optparse import OptionParser


def argument_analysis():
    """
This will analyze arguments, and return the region as a string, the filter as a dictionary, and the command as a string.
    :return: region,filters,command
    """
    parser = OptionParser()
    parser.add_option("-r", "--region", dest='region',
                      help="Filter by region.")
    parser.add_option("-n", "--name", dest='name',
                      help="Filter by hostname.")
    parser.add_option("-P", "--project", dest='project',
                      help="Filter by Project tag.")
    parser.add_option("-U", "--usage", dest='usage',
                      help="Filter by Usage tag.")
    parser.add_option("-i", "--instance_id", dest='instance_id',
                      help="Filter by instance_id.")
    parser.add_option("-t", "--type", dest='type',
                      help="Filter by instance_size.")
    parser.add_option("-p", "--ip", dest='internal_ip',
                      help="Filter by internal_ip")
    parser.add_option("-c", "--command", dest='command',
                      help="stop/start, or check the status of instances.")
    parser.add_option("-a", "--all", dest='all', default=False, action='store_true',
                      help="No filter, display status of all servers.")
    (options, args) = parser.parse_args()  # Grab Options specifed from above, as well as actual Arguments.

    options = vars(options)  # Convert 'options' into dictionary: key=dest_name, value=dest_value

    # Getting variables for dictionary below.
    region_filter = options['region']
    name_filter = options['name']
    project_filter = options['project']
    usage_filter = options['usage']
    instance_filter = options['instance_id']
    type_filter = options['type']
    ip_filter = options['internal_ip']
    all_filter = options['all']

    region = region_filter if region_filter else 'us-east-1' # Return 'us-east-1' region is not specified.

    filters = {'tag:Name': name_filter, 'tag:Project': project_filter, 'tag:Usage': usage_filter,
               'instance-id': instance_filter, 'instance_type': type_filter, 'private-ip-address': ip_filter,
               'all': all_filter}

    command = 'No commands.' if not args else args  #Return "No commands" if no command is specified.

    return region, filters, command


if __name__ == '__main__':
    opts_and_args = argument_analysis()
    print "Region: " + str(opts_and_args[0])
    print "Filters: " + str(opts_and_args[1])
    print "Command: " + str(opts_and_args[2])

As you can see, you can apply whatever logic you want to based on the returned object, or within the definition. Thanks everybody for your assistance on this one.


回答1:


Maybe you can do this with argparse, but another option is to use the sys module

import sys
print sys.argv # prints command line arguments

sys.argv has the command line arguments in a list, so you can check the last one for whatever:

if sys.argv[-1] != 'start':
    print "Error, expected <something>"
    // quit



回答2:


Partially the same as Ben's answer, but extended with regex to avoid declaring an if statement for each case, e.g. start, stop.

import sys
import re

a = sys.argv[-1]

if not re.search(r"^(start|stop|restart|status)$", a):
    raise Exception("start, stop, restart or status should be passed to this script instead of: \""+a+"\"")



回答3:


I recommend taking a look at docopt. It's not in the standard library, but it's definitely more powerful and intuitive. For example, in your case you could just do this:

docstring='''My Program.

Usage: my_prog [options] (flag1|flag2|flag3) (start|stop|restart|status)

Options:
  -a  stuff about this
  -b  more stuff
  -c  yet more stuff
  -d  finally stuff'''

from docopt import docopt
parsed = docopt(docstring)


来源:https://stackoverflow.com/questions/24833054/argument-parsing-in-python-required-vs-optional

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!