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
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
Find Column Name in Pandas That Matches an Array
Change User-Agent for Selenium Web-Driver
How to Apply Piecewise Linear Fit in Python
Python: How to Get Stdout After Running Os.System
How to Handle Elements Inside Shadow Dom from Selenium
Unicodedecodeerror When Redirecting to File
How to Retrieve Inserted Id After Inserting Row in SQLite Using Python
Monitoring Contents of Files/Directories
How to Make a Multidimension Numpy Array with a Varying Row Size
Grouping/Clustering Numbers in Python
Collision Between Masks in Pygame
Timeout for Python Requests.Get Entire Response
Could Not Find a Version That Satisfies the Requirement Tensorflow
Coalesce Values from 2 Columns into a Single Column in a Pandas Dataframe
Function Changes List Values and Not Variable Values in Python
How to Display Full Output in Jupyter, Not Only Last Result
Flask SQLalchemy Query, Specify Column Names
Reloading Module Giving Nameerror: Name 'Reload' Is Not Defined