Python argparse: Make at least one argument required

前端 未结 11 1734
谎友^
谎友^ 2020-12-13 01:39

I\'ve been using argparse for a Python program that can -process, -upload or both:

parser = argparse.ArgumentParser(de         


        
11条回答
  •  暗喜
    暗喜 (楼主)
    2020-12-13 01:47

    Requirements Review

    • use argparse (I will ignore this one)
    • allow one or two actions to be called (at least one required).
    • try to by Pythonic (I would rather call it "POSIX"-like)

    There are also some implicit requirements when living on command line:

    • explain the usage to the user in a way which is easy to understand
    • options shall be optional
    • allow specifying flags and options
    • allow combining with other parameters (like file name or names).

    Sample solution using docopt (file managelog.py):

    """Manage logfiles
    Usage:
        managelog.py [options] process -- ...
        managelog.py [options] upload -- ...
        managelog.py [options] process upload -- ...
        managelog.py -h
    
    Options:
        -V, --verbose      Be verbose
        -U, --user   Username
        -P, --pswd   Password
    
    Manage log file by processing and/or uploading it.
    If upload requires authentication, you shall specify  and 
    """
    if __name__ == "__main__":
        from docopt import docopt
        args = docopt(__doc__)
        print args
    

    Try to run it:

    $ python managelog.py
    Usage:
        managelog.py [options] process -- ...
        managelog.py [options] upload -- ...
        managelog.py [options] process upload -- ...
        managelog.py -h
    

    Show the help:

    $ python managelog.py -h
    Manage logfiles
    Usage:
        managelog.py [options] process -- ...
        managelog.py [options] upload -- ...
        managelog.py [options] process upload -- ...
        managelog.py -h
    
    Options:
        -V, --verbose      Be verbose
        -U, --user   Username
        -P, --pswd   P    managelog.py [options] upload -- ...
    
    Manage log file by processing and/or uploading it.
    If upload requires authentication, you shall specify  and 
    

    And use it:

    $ python managelog.py -V -U user -P secret upload -- alfa.log beta.log
    {'--': True,
     '--pswd': 'secret',
     '--user': 'user',
     '--verbose': True,
     '-h': False,
     '': ['alfa.log', 'beta.log'],
     'process': False,
     'upload': True}
    

    Short alternative short.py

    There can be even shorter variant:

    """Manage logfiles
    Usage:
        short.py [options] (process|upload)... -- ...
        short.py -h
    
    Options:
        -V, --verbose      Be verbose
        -U, --user   Username
        -P, --pswd   Password
    
    Manage log file by processing and/or uploading it.
    If upload requires authentication, you shall specify  and 
    """
    if __name__ == "__main__":
        from docopt import docopt
        args = docopt(__doc__)
        print args
    

    Usage looks like this:

    $ python short.py -V process upload  -- alfa.log beta.log
    {'--': True,
     '--pswd': None,
     '--user': None,
     '--verbose': True,
     '-h': False,
     '': ['alfa.log', 'beta.log'],
     'process': 1,
     'upload': 1}
    

    Note, that instead of boolean values for "process" and "upload" keys there are counters.

    It turns out, we cannot prevent duplication of these words:

    $ python short.py -V process process upload  -- alfa.log beta.log
    {'--': True,
     '--pswd': None,
     '--user': None,
     '--verbose': True,
     '-h': False,
     '': ['alfa.log', 'beta.log'],
     'process': 2,
     'upload': 1}
    

    Conclusions

    Designing good command line interface can be challenging sometime.

    There are multiple aspects of command line based program:

    • good design of command line
    • selecting/using proper parser

    argparse offers a lot, but restricts possible scenarios and can become very complex.

    With docopt things go much shorter while preserving readability and offering high degree of flexibility. If you manage getting parsed arguments from dictionary and do some of conversions (to integer, opening files..) manually (or by other library called schema), you may find docopt good fit for command line parsing.

提交回复
热议问题