简体   繁体   English

Python中的参数解析(必需与可选)

[英]Argument parsing in Python (required vs. optional)

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'. 我希望这样,无论最后一个参数是'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. 我希望它使./argument_analysis_script.py在末尾需要“ stop | start |状态”。 I haven't had much luck getting help with the ARgumentParser(). 我不太幸运能获得有关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. 注意:如果不输入[stop | start | restart | status],我希望脚本停止运行,并说明需要[stop | start | restart | status]。

**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 . 在进行了更多挖掘之后,为了能够分析/使用命令行选项和参数,我偶然发现了OptionParser,我避免了它,因为docs.python.org声明已弃用 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. 感谢大家在此方面的协助。

Maybe you can do this with argparse, but another option is to use the sys module 也许您可以使用argparse做到这一点,但是另一种选择是使用sys模块

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: sys.argv在列表中具有命令行参数,因此您可以检查最后一个参数:

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

Partially the same as Ben's answer, but extended with regex to avoid declaring an if statement for each case, eg start , stop . 与Ben的答案部分相同,但使用regex进行了扩展,以避免为每种情况声明if语句,例如startstop

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+"\"")

I recommend taking a look at docopt . 我建议看看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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM