Simple Argparse Example Wanted: 1 Argument, 3 Results

Simple argparse example wanted: 1 argument, 3 results

My understanding of the original question is two-fold. First, in terms of the simplest possible argparse example, I'm surprised that I haven't seen it here. Of course, to be dead-simple, it's also all overhead with little power, but it might get you started.

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("a")
args = parser.parse_args()

if args.a == 'magic.name':
print 'You nailed it!'

But this positional argument is now required. If you leave it out when invoking this program, you'll get an error about missing arguments. This leads me to the second part of the original question. Matt Wilkie seems to want a single optional argument without a named label (the --option labels). My suggestion would be to modify the code above as follows:

...
parser.add_argument("a", nargs='?', default="check_string_for_empty")
...
if args.a == 'check_string_for_empty':
print 'I can tell that no argument was given and I can deal with that here.'
elif args.a == 'magic.name':
print 'You nailed it!'
else:
print args.a

There may well be a more elegant solution, but this works and is minimalist.

Very basic example of argparse?

here is a very simple example.

You have to save it as arg_parse.py and run it in your terminal with

python3 arg_parse.py -o hello_world

it will print hello world in your terminal
Sample Image

CODE:

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('-o', "--opts",)

args = parser.parse_args()
opts = args.opts
print(opts)

Explanation:
It takes whatever your enter in the terminal after --opts (or short -o) and saves it to variable args.opts you can use it then as you would normally in python

Python argparse example?

import argparse

# Use nargs to specify how many arguments an option should take.
ap = argparse.ArgumentParser()
ap.add_argument('-a', nargs=2)
ap.add_argument('-b', nargs=3)
ap.add_argument('-c', nargs=1)

# An illustration of how access the arguments.
opts = ap.parse_args('-a A1 A2 -b B1 B2 B3 -c C1'.split())

print(opts)
print(opts.a)
print(opts.b)
print(opts.c)

# To require that at least one option be supplied (-a, -b, or -c)
# you have to write your own logic. For example:
opts = ap.parse_args([])
if not any([opts.a, opts.b, opts.c]):
ap.print_usage()
quit()

print("This won't run.")

Why does argparse not accept -- as argument?

This looks like a bug. You should report it.

This code in argparse.py is the start of _get_values, one of the primary helper functions for parsing values:

if action.nargs not in [PARSER, REMAINDER]:
try:
arg_strings.remove('--')
except ValueError:
pass

The code receives the -- argument as the single element of a list ['--']. It tries to remove '--' from the list, because when using -- as an end-of-options marker, the '--' string will end up in arg_strings for one of the _get_values calls. However, when '--' is the actual argument value, the code still removes it anyway, so arg_strings ends up being an empty list instead of a single-element list.

The code then goes through an else-if chain for handling different kinds of argument (branch bodies omitted to save space here):

# optional argument produces a default when not present
if not arg_strings and action.nargs == OPTIONAL:
...
# when nargs='*' on a positional, if there were no command-line
# args, use the default if it is anything other than None
elif (not arg_strings and action.nargs == ZERO_OR_MORE and
not action.option_strings):
...
# single argument or optional argument produces a single value
elif len(arg_strings) == 1 and action.nargs in [None, OPTIONAL]:
...
# REMAINDER arguments convert all values, checking none
elif action.nargs == REMAINDER:
...
# PARSER arguments convert all values, but check only the first
elif action.nargs == PARSER:
...
# SUPPRESS argument does not put anything in the namespace
elif action.nargs == SUPPRESS:
...
# all other types of nargs produce a list
else:
...

This code should go through the 3rd branch,

# single argument or optional argument produces a single value
elif len(arg_strings) == 1 and action.nargs in [None, OPTIONAL]:

but because the argument is missing from arg_strings, len(arg_strings) is 0. It instead hits the final case, which is supposed to handle a completely different kind of argument. That branch ends up returning an empty list instead of the '--' string that should have been returned, which is why args.delimiter ends up being an empty list instead of a '--' string.


This bug manifests with positional arguments too. For example,

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('a')
parser.add_argument('b')

args = parser.parse_args(["--", "--", "--"])

print(args)

prints

Namespace(a='--', b=[])

because when _get_values handles the b argument, it receives ['--'] as arg_strings and removes the '--'. When handling the a argument, it receives ['--', '--'], representing one end-of-options marker and one actual -- argument value, and it successfully removes the end-of-options marker, but when handling b, it removes the actual argument value.

Accepting more arguments with argparse

To be able to pass the same option multiple times to your script, you can use append action of argparse (as noted by @barny).

Then, you should take the list of values, and call function a() for every value of the list that you received from argparse.

Here's the code:

import argparse

parser = argparse.ArgumentParser()

# You must provide the flag once per input.
parser.add_argument('-a', '--funcA', help='do A', action='append')
parser.add_argument('-b', '--funcB', help='do B', action='append')

args = parser.parse_args()
if args.funcA:
for elemA in args.funcA:
print("a: ", elemA)
for elemB in args.funcB:
print("b :", elemB)

And the output:

python3 parseab.py -a 11 -b 22 -a 33
a: 11
a: 33
b : 22

Here is the answer that gives more details on other possibilities:
How can I pass a list as a command-line argument with argparse?

Automation of tasks with argparse Python3

parser = argparse.ArgumentParser(description="This allows quick opening of applications used within the school day")

parser.add_argument('command', choices=['start', 'engine', 'bus', 'cs', 'python'])

args = parser.parse_args()

try:
if args.command:
if args.command == "engine":
engineering()
elif args.command == "cs":
computer_science()
elif args.command == "python":
python()
elif args.command == "bus":
business()
elif args.command == "start":
std_day()
except Exception as e:
print("An error has occurred", e)

Processing arguments for subprocesses using argparse: Expected one argument

I found an ugly workaround but if it exit, I would enjoy a better solution.

I added the following function:

def __workaround_for_extra_utr_args():
"""This workaround is necessary because utr can receives args at \"--repeat=0\" which are not processable by arg parse, even as a string"""
import sys

index_of_extra_args = [sys.argv.index(v) for v in ['-e', '--extra_utr_args'] if v in sys.argv]
space = " "

if index_of_extra_args:
index_of_extra_args = index_of_extra_args[0]

if space not in sys.argv[index_of_extra_args + 1]:
sys.argv[index_of_extra_args + 1] = sys.argv[index_of_extra_args + 1] + space

Call it before calling the parser, and it will be able to return the string, it is then possible to remove the extra space after the parsing.

argparse define fraction as default parameter

bash doesn't handle floating arithmetic, so instead you need an external tool like bc(1) (which is usually bundled with bash):

python main.py --eps $(bc <<< "scale=5; 1./2.")

where scale is the number of digits after the decimal point, the default being zero.

On many shells (including some versions of bash), python main.py --eps "$((1./2.))" would work.

Source



Related Topics



Leave a reply



Submit