3

I'm trying to solve a problem with python's argparse function

What I would like to achieve is, that if -k argument is specified, it's set to its default value (let's say 5), however if -k=3 is set, 'k' now contains 3...

Here is an example:

python3 test.py -k

Namespace(k==5)

python3 test.py -k=3

Namespace(k==3)

Is it possible to get something like this ?

test.py

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('-k ', metavar='n', type=int, default=5, dest='number')
args = parser.parse_args()
print(args)

Thanks in advance

2
  • Hi Robert, I've edited post Commented Mar 30, 2014 at 23:09
  • 1
    What if there isn't a -k? What value do you want? Commented Mar 31, 2014 at 1:33

2 Answers 2

1

What about this:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('-k',metavar='n', dest='number', action='append', nargs='?', const=5)
args = parser.parse_args()

print(args.number[0])

'python3 test.py -k' outputs:

5

'python3 test.py -k=3' outputs:

3

An example using sys:

import sys

k = 5
for opt in sys.argv:
    if opt.split('=')[0] == '-k':
        if '=' in opt:
            print(opt.split('=')[1])
        if '=' not in opt:
            print(k)
    elif len(sys.argv) is 1:
        print('No arguments were supplied')
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for response, it works, however, the problem is that there has to be '=' symbol between 'k' and number :/ So possible options are: -k=x (k contains number defined by user) -k (k contains number defined by default)
@Creck there was a trailing whitespace on the -k flag I updated the argparse version it should now work
Thank you, really appreciate that, so, it looks like it cant be done just with argparse right ? :/
@Creck ... since the dest for the -k flag is number the variable k is not being assigned in Namespace. By using args.number[0] we can access the number supplied by the user. You could change the dest variable to k, so that it outputs k in Namespace when printing args... But I guess I just don't understand why this is not enough to access the information given by the user? Can you please elaborate on this? Does the output have to be exactly Namespace(k==5)? Why does it have to be in that format?
Ah, sorry I've made a mistake in output :( it should be Namespace(k=5)...it's part of my school project where user have 3 choices to passing argument: 1st: User do not specify -k at all 2nd: User specify -k without any number, so default one is used (for example 5) 3rd: User specify -k=x where x is greater or equal to zero
0

It's a bit of a hack, but you could replace all equal signs in the arguments with spaces and then use argparse on them. This could work better if you want to still use argparse, e.g. for other arguments.

It would mean both -k=3 and -k 3 would work. Though also -k=3=-k=4=-k would be parsed without error.

Adapted from jmunsch's answer:

import argparse
import sys

# split all args with equal sign
args = []
for arg in sys.argv[1:]:
    args.extend(arg.split('='))

# parse the args
parser = argparse.ArgumentParser()
parser.add_argument('-k', metavar='n', type=int, dest='number',
                    action='append', nargs='?', const=5)
args = parser.parse_args(args)
print(args.number[0])

This could be made more intelligent by only splitting args that start with '-k=':

# split all args with equal sign
args = []
for arg in sys.argv[1:]:
    if arg[:2] == '-k=':
        args.extend(arg.split('='))
    else:
        args.append(arg)

1 Comment

Thanks for your response, however, I have to prevent to accept options like you have mentioned above :(

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.