How to use python argparse with args other than sys.argv?
Asked Answered
T

3

28

Is there a way to use argparse with any list of strings, instead of only with sys.argv?

Here's my problem: I have a program which looks something like this:

# This file is program1.py
import argparse

def main(argv):
    parser = argparse.ArgumentParser()
    # Do some argument parsing

if __name__ == '__main__':
    main(sys.argv)

This works fine when this program is called straight from the command line. However, I have another python script which runs batch versions of this script with different commandline arguments, which I'm using like this:

import program1

arguments = ['arg1', 'arg2', 'arg3']
program1.main(arguments)

I still want to be able to parse the arguments, but argparse automatically defaults to using sys.argv instead of the arguments that I give it. Is there a way to pass in the argument list instead of using sys.argv?

Terti answered 9/8, 2016 at 14:38 Comment(1)
becouse allmost all examples do not use sys.argvWheeze
A
20

You can pass a list of strings to parse_args:

parser.parse_args(['--foo', 'FOO'])
Amphibolous answered 9/8, 2016 at 14:42 Comment(0)
A
12

Just change the script to default to sys.argv[1:] and parse arguments omitting the first one (which is the name of the invoked command)

import argparse,sys

def main(argv=sys.argv[1:]):
    parser = argparse.ArgumentParser()
    parser.add_argument("--level", type=int)
    args = parser.parse_args(argv)

if __name__ == '__main__':
    main()

Or, if you cannot omit the first argument:

import argparse,sys

def main(args=None):
    # if None passed, uses sys.argv[1:], else use custom args
    parser = argparse.ArgumentParser()
    parser.add_argument("--level", type=int)
    args = parser.parse_args(args)

    # Do some argument parsing

if __name__ == '__main__':
    main()

Last one: if you cannot change the called program, you can still do something

Let's suppose the program you cannot change is called argtest.py (I added a call to print arguments)

Then just change the local argv value of the argtest.sys module:

import argtest
argtest.sys.argv=["dummy","foo","bar"]
argtest.main()

output:

['dummy', 'foo', 'bar']    
Authoritarian answered 9/8, 2016 at 14:41 Comment(0)
F
0

Python argparse now has a parameter nargs for add_argument (https://docs.python/3/library/argparse.html).

It allows us to have as many arguments as we want for a named parameter (here, alist)

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--alist", nargs="*")
args = parser.parse_args()

print(args.alist)

All command line values that follow --alist are added to a list.

Example:

$ python3 argparse-01.py --alist fred barney pebbles "bamm bamm"
['fred', 'barney', 'pebbles', 'bamm bamm']

As you see, it is allowed to quote the arguments, but not necessary unless you need to protect a space.

Fears answered 29/6, 2021 at 19:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.