user2753523
user2753523

Reputation: 483

How to access optional parameter in this case?

How to access optional parameter in this case?

I have a parser like

import argparse
parser = argparse.ArgumentParser(prog='some_prog',formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument("tableName")
parser.add_argument("--duration",help = """It is an optional parameter.""")
parser.add_argument("columns",nargs=argparse.REMAINDER)
args = parser.parse_args()
print args.duration

When I execute "python some_prog.py T1 --duration=1278678-3275678678 column1 column2" using command prompt

args.duration is returning None

How can I access "duration"?

Please suggest me the solution...

Please let me know if the way I am using for nargs is wrong?

Upvotes: 0

Views: 596

Answers (2)

hpaulj
hpaulj

Reputation: 231385

The resulting namespace is:

Namespace(columns=['--duration=1278678-3275678678', 'column1', 'column2'], duration=None, tableName='T1')

columns grabbed everything, the REMAINDER.

If I give it: "--duration=1278678-3275678678 T1 column1 column2", I get:

Namespace(columns=['--duration=1278678-3275678678', 'column1', 'column2'], duration=None, tableName='T1')

Let's change the nargs=REMAINDER to nargs='*'. Now the first case gives

error: unrecognized arguments: column1 column2

The issue is how a positional that can take zero or more values is consumed. See this SO discussion: https://stackoverflow.com/a/18645430/901925 'Python argparse: Combine optional parameters with nargs=argparse.REMAINDER.

In short columns either consumes everything after T1, or it consumes the [] between T1 and --duration.

Change it to nargs='+', and it works. Why? Because it has to match one or more strings. Now it does not fit into the gap.

The issue has been raised in other SO threads, and on Python bugs (intermixing optionals and positionals)

But in the meantime your choices are:

  • put optionals like --duration before positionals
  • use '+' instead of '*' or 'REMAINDER'
  • parse the input in a couple of steps.

Upvotes: 0

justhalf
justhalf

Reputation: 9107

You should put the optional arguments first:

python some_prog.py --duration=1278678-3275678678 T1 column1 column2

works well for me.

T1 will get assigned to tableName, while "column1 column2" will get assigned to columns

This is because after getting the positional argument tableName, it will take the rest as part of argparse.REMAINDER.

I remember seeing this in another SO question, but I couldn't find it.

To make it possible to put your tableName as first argument, you can use parse_known_args instead of parse_args and remove the definition of column:

import argparse
parser = argparse.ArgumentParser(prog='some_prog',formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument("tableName")
parser.add_argument("--duration",help = """It is an optional parameter.""")

(args, the_rest) = parser.parse_known_args()
print args.tableName
print args.duration
print the_rest

which will give:

T1
1234
['column1', 'column2']

Upvotes: 0

Related Questions