Разбор аргументов в Python (обязательный или необязательный)

В настоящее время я работаю над сценарием, который сможет принимать несколько флагов. Я хочу, чтобы независимо от того, каким последним аргументом должен быть "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()

Я хочу, чтобы./argument_analysis_script.py потребовал 'stop|start|status' в конце. Мне не повезло, что я получил помощь с ARgumentParser(). Если у кого-то есть какие-либо предложения, это было бы очень полезно.

Спасибо заранее за ваше время.

ПРИМЕЧАНИЕ. Я бы хотел, чтобы скрипт остановился, если [stop | start | restart | status] не введен, и объяснил, что требуется [stop | start | restart | status].

** ОБНОВЛЕНИЕ ** ** ОБНОВЛЕНИЕ ** ** ОБНОВЛЕНИЕ **

После еще нескольких копаний, чтобы иметь возможность анализировать / использовать параметры командной строки и аргументы, я наткнулся на OptionParser, которого я избегал, поскольку http://docs.python.org/ заявляет, что он устарел. В любом случае, поскольку это единственное, что я смог найти, чтобы дать мне именно то, что я хотел, вот обновление того, что я получил:

#!/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])

Как видите, вы можете применять любую логику, какую захотите, на основе возвращаемого объекта или в пределах определения. Спасибо всем за вашу помощь в этом.

3 ответа

Может быть, вы можете сделать это с argparse, но другой вариант заключается в использовании sys модуль

import sys
print sys.argv # prints command line arguments

sys.argv имеет аргументы командной строки в списке, так что вы можете проверить последний из них:

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

Частично так же, как ответ Бена, но расширен с regex чтобы не объявлять оператор if для каждого случая, например 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+"\"")

Я рекомендую взглянуть на докопт. Его нет в стандартной библиотеке, но он определенно более мощный и интуитивно понятный. Например, в вашем случае вы можете просто сделать это:

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)
Другие вопросы по тегам