1

I'm trying to build a process with some parsing option, some mandatory and others optinal. I have a problem with the following code:

    bandlist=[1,2,3,4,5,6,7,8]
    process=['rad', 'ref', 'radref']
    sensors=['LC', 'LO', 'LE', 'LT']
    series=['4', '5', '7', '8']
    usage = "usage: %prog [options] "
    parser = argparse.ArgumentParser(usage=usage)

    parser.add_argument('-d', '--directory', dest='directory', action='store', type=str, \
                      help='complete path of landsat product folder: mydir/filename/')

    parser.add_argument('-p', '--process', dest='operation', action='store', choices = process, \
                      help='process requested: radiance, reflectance, both', default='rad')

    parser.add_argument('-l', '--series', dest='satellite', action='store', choices = series , \
                      help='Landsat series:4, 5, 7, 8')

    parser.add_argument('-s', '--sensor', dest='sensor', action='store', choices = sensors, \
                      help='sensor acronymous, for example LO for Landsat OLI, or LE for Landsat ETM+, etc..', default=None)

    parser.add_argument('-o', '--output',   dest='output', type=str, \
            help='Directory of output raster. \n \
                Unless specified, output directory will be workDirectory/results/datafolder/. \n \
                If specified, the output directory wil be mydirectory/results/filename/rad (and/or ref)/', default=None)

    parser.add_argument('-x', action='store_true', dest='bool', help='activate iterative radiance and/or reflectance computation for all the bands', default=False)

    parser.add_argument('-b', '--bands', dest='bands', choices = bandlist, type=int, \
                      help='bands to process', nargs='*', default=None)

    (options, args) = parser.parse_args()

and there is the following error:

Traceback (most recent call last):
File "C:\Users\lbernardi\Desktop\extract\LandsatTMroutine_RadiometricCorrection_1.0.py", line 1210, in <module>
main()
File "C:\Users\lbernardi\Desktop\extract\LandsatTMroutine_RadiometricCorrection_1.0.py", line 784, in main
(options, args) = parser.parse_args()
TypeError: 'Namespace' object is not iterable

I don't understand what the error is about. Thank for your help

2
  • (options, args) = is the optparse way. argparse returns both types of arguments in one Namespace object. Commented Nov 25, 2015 at 16:42
  • Since you are moving from optparse to argparse (as seen in your previous question), you may need to study the last section of the argparse docs in more detail. Commented Nov 25, 2015 at 17:07

2 Answers 2

4

parse_args doesn't return two items, it returns one.

args = parser.parse_args()
Sign up to request clarification or add additional context in comments.

Comments

0

The error was issued by the interpreter while performing the (options, args) = ... assignment. The parser returned one object, a argparse.Namespace. But the assignment tries to split it into two items, e.g.

(options, args) = (args[0], args[1])

But the Namespace class definition does not implement a list or tuple like iteration. A custom Namespace class could, in theory, do so.

That's the technical detail behind the error. The practical issue is that argparse differs from optparse.

From the end of the argparse docs:

Replace (options, args) = parser.parse_args() with args = parser.parse_args() and add additional ArgumentParser.add_argument() calls for the positional arguments. Keep in mind that what was previously called options, now in argparse context is called args.

optparse processes all the flagged strings, and puts their values in an options object (I forget its exact nature). Strings that it can't process are returned as a list as the 2nd return value.

argparse expects you to define all arguments, both the flagged ones (called 'optionals') and unflagged ones (called 'positionals'). So values that in optparse would appear in the args list, appear under their own 'name/dest' in the argparse namespace.

There is another way of calling the argparse parser, parser.parse_known_args that behaves more like optparse. Strings it can't handle are returned in an extras list.

You mention that some of your arguments are required and some are not. At a first glance, your code makes everything 'optional'. That is, if you don't include the relevant flag in the commandline, that argument will get its default value.

One of your arguments uses nargs='*'. If that isn't specified the default will be None or [] (I forget the details).

You can also specify required=True parameter which makes an 'optional' required. Sorry about the confusing terminology. In that case, the parser will raise an error if you don't supply the flag in the commandline.

I didn't look much at your previous optparse question to see whether you expected an values in the args variable. In argparse usage those are 'positionals' and are required (unless their nargs makes them 'optional').

So while the simple fix is just use args = parser.parse_args(), I suspect there's more under the surface.

A style point:

parser.add_argument('-d', '--directory', dest='directory', action='store', type=str, \
                  help='complete path of t product folder: mydir/filename/')

can be simplified to

parser.add_argument('-d', '--directory', \
                  help='complete path of landsat product folder: mydir/filename/')

If not given dest is infered from the first long flag string. store is the default action value, and str is the default type.

In argparse, type is a function, one that converts the input string to something else. int and float are the most common alternatives. str works because it does nothing - returns the same string it was given. argparse actually uses an identify lambda function as the default type (e.g. lambda x:x).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.