What is the canonical way of handling sys arguments in Python?
Question: Let's say I want to make a hashing script:

    
    
    ### some code here
    
    def hashlib_based(path, htype='md5', block_size=2**16):
        hash = eval(htype)
        with open(path, 'rb') as f:
            for block in iter(lambda: f.read(block_size), ''):
                hash().update(block)
            f.close()
        return hash().hexdigest()
    
    ### some code here
    

As you can see, I have the opportunity to use different flags to allow me to
change the hash type or the block size when I call the script from the command
line (for example `./myscript.py -sha1 -b 512 some_file.ext`). The thing is, I
don't have any clue on how should I do this in order to keep my code as clean
and readable as possible. How do I deal with `sys.argv`?

First of all, how do I check if the user uses the correct flags? I need to do
that in order to print out a **usage** message. Do I make a list with all the
flags, then I check if the user uses one that is in that list?

Should I do all these things inside `main()` or should I do place them in a
different function?

Should I construct my flags with a hyphen-minus in front of them (like this:
-a, -b) or without one? To check if a certain flag is present in sys.argv, do
I simply do something like:

    
    
    if '-v' in sys.argv:
        verbose = True
    

?

Because sys.argv has indexes, what is the best way to ignore the order of the
flags - or in other words, should `./myscript.py -a -b` be the same as
`./myscript.py -b -a`? While it certainly makes the job easier for the common
user, is it common practice to do so?

[I saw something similar but for
C#.](http://stackoverflow.com/questions/491595/best-way-to-parse-command-line-
arguments-in-c?rq=1) Is there a similar concept in Python? The thing is, as
simple as these things are, they get out of hands quickly - for me at least. I
end up doing a mess. What is your approach to this problem?


Answer: For _really simple_ use cases, such as checking the presence of one argument,
you can do a check like you're showing, i.e.:

    
    
    if '-v' in sys.argv: ...
    

which is the quick'n dirty way of checking arguments. But once your project
gets a bit more serious, you definitely need to use an argument parsing
library.

And there are a few ones to handle argument parsing: there is the now
deprecated `getopt` (I won't give a link), the most common one is
[argparse](http://docs.python.org/3.3/library/argparse.html) which is included
in any python distribution.

    
    
    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument('-a', '--a-long', help='a help')
    parser.add_argument('-b', '--b-long', help='b help')
    args = parser.parse_args()
    

then you can call your `script -a -b` or `script -b -a` which will be
equivalent. And for free, you've got `script -h` for free! :-)

Though, my preference is now over [docopt](http://docopt.org), imho, which is
way simpler and more elegant, for the same example:

    
    
    """
    My script.
    
    usage:
        myscript -a | --along
        myscript -b | --blong
    
    Options:
      -a --along     a help
      -b --blong     b help
    """
    
    from docopt import docopt
    arguments = docopt(__doc__, version='myscript 1.0')
    print(arguments)
    

HTH

