Conditional command line arguments in Python using argparse

前端 未结 4 1493
失恋的感觉
失恋的感觉 2020-12-13 18:16

I\'d like to have a program that takes a --action= flag, where the valid choices are dump and upload, with upload being t

相关标签:
4条回答
  • 2020-12-13 18:36

    It depends what you consider "doing all the logic yourself". You can still use argparse and add the dump option as follows with minimal effort without resorting to sub-commands:

    from argparse import ArgumentParser
    from sys import argv
    
    parser = ArgumentParser()
    action_choices = ['upload', 'dump']
    parser.add_argument('--action', choices=action_choices, default=action_choices[1])
    parser.add_argument('--dump-format', required=(action_choices[1] in argv))
    

    This way argparse won't care about the dump format if the dump action wasn't selected

    0 讨论(0)
  • 2020-12-13 18:48

    Another way to approach the problem is by using subcommands (a'la git) with "action" as the first argument:

    script dump --dump-format="foo"
    script upload
    
    0 讨论(0)
  • 2020-12-13 18:50

    The argparse module offers a way to do this without implementing your own requiredness checks. The example below uses "subparsers" or "sub commands". I've implemented a subparser for "dump" and one for "format".

    import argparse
    
    parser = argparse.ArgumentParser()
    parser.add_argument('file', help='The file you want to act on.')
    subparsers = parser.add_subparsers(dest='subcommand')
    
    #  subparser for dump
    parser_dump = subparsers.add_parser('dump')
    # add a required argument
    parser_dump.add_argument(
        'format',
        choices=['csv', 'json'],
        help='Dump the file in this format.')
    
    #  subparser for upload
    parser_upload = subparsers.add_parser('upload')
    # add a required argument
    parser_upload.add_argument(
        'server',
        choices=['amazon', 'imgur'],
        help='Upload the file to this service.')
    
    args = parser.parse_args()
    print args
    if args.subcommand == 'dump':
        print 'I will now dump "%s" in the %s format' % (args.file, args.format)
    if args.subcommand == 'upload':
        print 'I will now upload "%s" to %s' % (args.file, args.server)
    

    That looks like this on the command line:

    $ python ap.py 
    usage: ap.py [-h] file {upload,dump} ...
    ap.py: error: too few arguments
    $ python ap.py tmp.txt 
    usage: ap.py [-h] file {upload,dump} ...
    ap.py: error: too few arguments
    $ python ap.py tmp.txt upload
    usage: ap.py file upload [-h] {amazon,imgur}
    ap.py file upload: error: too few arguments
    $ python ap.py tmp.txt upload amazo
    usage: ap.py file upload [-h] {amazon,imgur}
    ap.py file upload: error: argument server: invalid choice: 'amazo' (choose from 'amazon', 'imgur')
    $ python ap.py tmp.txt upload amazon
    Namespace(file='tmp.txt', server='amazon', subcommand='upload')
    I will now upload "tmp.txt" to amazon
    $ python ap.py tmp.txt upload imgur
    Namespace(file='tmp.txt', server='imgur', subcommand='upload')
    I will now upload "tmp.txt" to imgur
    $ python ap.py tmp.txt dump
    usage: ap.py file dump [-h] {csv,json}
    ap.py file dump: error: too few arguments
    $ python ap.py tmp.txt dump csv
    Namespace(file='tmp.txt', format='csv', subcommand='dump')
    I will now dump "tmp.txt" in the csv format
    $ python ap.py tmp.txt dump json
    Namespace(file='tmp.txt', format='json', subcommand='dump')
    I will now dump "tmp.txt" in the json format
    

    More info: http://docs.python.org/dev/library/argparse.html#argparse.ArgumentParser.add_subparsers

    0 讨论(0)
  • 2020-12-13 18:54

    You could use parser.error:

    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument('--action', choices=['upload', 'dump'], default='dump')
    parser.add_argument('--dump-format')
    args = parser.parse_args()
    if args.action != 'dump' and args.dump_format:
        parser.error('--dump-format can only be set when --action=dump.')
    
    0 讨论(0)
提交回复
热议问题