is there a better/shorter/more normal way of doing this:
try:
sys.argv[1]
except:
mod.init()
else:
mod.init("y") if sys.argv[1]=="y" else mod.init()
I soon discovered function if else doesn't work if argv[1] doesn't exist.
Use argparse, and make sure the default value of the command line argument is whatever the default value of mod.init's parameter is. You can make the argument optional and restrict it to a value of y.
When you run the script, you'll get an error if anything other than y is used for the option positional argument, so if mod.init is called at all, it will only be called with "y" or None as its argument.
import argparse
p = argparse.ArgumentParser()
p.add_argument("init_arg", choices=["y"], nargs='?', default=None)
args = p.parse_args()
mod.init(args.init_arg)
Related
Using python 3.8 argparse:
def_value= 'whatever'
argParser.add_argument ("-w", "--whatever", type=str, nargs=1, default=def_value, help="Whatever. Defaults to %s" % def_value)
args= argParser.parse_args()
print (args.whatever)
If I call my program passing a option -w with a value, args.whatever is a list. I mean:
myprog -w just_a_test
[just_a_test]
but, I pass nothing, the default argument is a string.
myprog
whatever
This is annoying, I mean, I have to test the type of args.whatever before using it;
If it is a is a string, just use it as string; if it is a list, I have to use it as args.whatever[0], you see ?
What is the best way to deal with such thing ?
PS: I think it is specific to 3.x, as I recall 2.x returned strings all the time.
did you try to remove the nargs option?
using n_args parameter will wrap the value in a list, therefore, there are two options:
1.
remove nargs argument.
def_value= 'whatever'
argParser.add_argument("-w", "--whatever", type=str, default=def_value, help="Whatever. Defaults to %s" % def_value)
args= argParser.parse_args()
print(args.whatever)
argparse by default allows only one arg, so in this case, no matter passing an argument or not, you will always get a string, and you will get an error when you try to pass more than 1 value.
2.wrap def_value with a list:
def_value= ['whatever']
argParser.add_argument("-w", "--whatever", type=str, nargs=1, default=def_value, help="Whatever. Defaults to %s" % def_value)
args= argParser.parse_args()
print(args.whatever)
now both default and passed in value will be a list with a single string, and it will also raise an error when you pass more than 1 value.
Both solutions above should accomplish the same goal, depending on which you prefer
Attempting to pass an undetermined amount of integers using argparse. When I input: py main.py 3 2
%%writefile main.py
import sorthelper
import argparse
integers = 0
#top-level parser creation
parser = argparse.ArgumentParser("For sorting integers")
nargs = '+' #-> gathers cmd line arguments into a list
args = parser.add_argument('-f', metavar='N', type=int, nargs='+', help='yada yada yada')
args = parser.parse_args()
print(sorthelper.sortNumbers(args))
%%writefile sorthelper.py
def sortNumbers(args):
sorted(args)
Error Namespace Argument is not iterable
I think is is because I am passing an argument that is not of the correct type. After reading through all the documentation I could find I cannot figure out how to make this work. I want the program to sort the numbers I am passing.
parser.parse_args() returns a Namespace object, which is an object whose attributes represent the flags that were parsed. It is not iterable.
It seems like you want to get the command-line arguments given after -f, in which case you would take that particular flag out of the Namespace object:
print(sorthelper.sortNumbers(args.f))
Also, your code as you currently have it will print None, because sortNumbers() doesn't return anything. The built-in sorted() function does not sort in place (though list.sort() does, if you want to use that), so you have to actually do
def sortNumbers(args):
return sorted(args)
I want to access and argument from my Python script using argparse:
parser = argparse.ArgumentParser()
# Required positional argument
parser.add_argument('mode', type=str,
help='Operation mode. Either "one" or "two".')
args = parser.parse_args()
print("Argument values:")
print(args.mode)
The variable "args.mode" contains the parameter name plus the value, like this "--mode One". But I want only the value part ("One"). I know I could split up the string but I want to know WHY argparse returns the parameter name. Is there a way to tell it I only want the value?
i want to use the optional arguments without - or --,
want to achive something like this:
scriptname install <other options>
scriptname uninstall <other options>
my code:
parser = argparse.ArgumentParser()
parser.add_argument("install","INSTALL",action='store_true',help="INSTALL SOMETHING",default="")
parser.add_argument("uninstall","UNINSTALL",action='store_true',help="UNINSTALL SOMETHING",default="")
args = parser.parse_args()
if args.install:
install logic
if args.uninstall:
uninstall logic
getting the error below
ValueError: invalid option string 'install': must start with a character '-'
A 'store_true' action does not take any arguments (nargs=0). A positional with that action is always true. And it will reject commandline strings like 'install' as unrecognized.
The dash is part of the definition of an optional. It identifies strings that serve as flags or names, as opposed to values. Without it you are defining a positional, an argument that is identified by position rather than a flag string.
So the normal optionals definitions would be:
parser.add_argument("--install",action='store_true',help="INSTALL SOMETHING")
parser.add_argument("--uninstall",action='store_true',help="UNINSTALL SOMETHING")
You could put those in a mutually exclusive group. With store_true the default is False, and if the flag is provided, without any argument, the attribute is set of True.
store_true is allowed with positionals, but doesn't make sense. A positional is required, so you can't get a False value.
You could define a positional with choices:
parser.add_argument('foo', choices=['install', 'uninstall'], help='...')
Then args.foo will have ones of those two string values.
The suggested use of subparsers is a variant on this choices positional - one where the action type is a special one that triggers a new parser.
What about using "sys" module instead of "argparse"? Then answer would be
import sys
if sys.argv[1] == "install":
install logic
elif sys.argv[2] == "uninstall":
uninstall logic
else:
exit
I would like to be able to specify an option to my program which acts as both a flag and as variable. For example:
I have an argument called "--logging". If this argument is not specified, I'd like it to be set to false (i.e. action='store_true'), but if the argument is specified, I'd like to do two things. 1) I'd like to set a default path of "./log_file.log" and 2) I'd like to allow the user to specify a different log file location.
Right, so I've come up with my own solution for this one. It relies on nargs. Here is the code first:
#!/usr/bin/python
# example.py
import argparse
parser = argparse.ArgumentParser(description="Example of a single flag acting as a boolean and an option.")
parser.add_argument('--foo', nargs='?', const="bar", default=False)
args = parser.parse_args()
if args.foo:
print args.foo
else:
print "Using the default, boolean False."
Given that example, here is what happens when we use it in the three possible situations:
> ./example.py
Using the default, boolean False.
> ./example.py --foo
bar
> ./example.py --foo baz
baz
Hopefully the above is pretty self-explanatory. In case it isn't, what is going on is that nargs='?' will use the 'default' value if the flag is not specified (boolean False in our case), the const value if the flag is specified without arguments, and the argument if the flag is specified with an argument. Be careful to not put any quotes around False; False is a built in type (boolean) and 'False' or "False" will evaluate as true.
Yes there is no issue. You can use this form explained in the excellent PyMOTW about argparse
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--logging', action='store_true', default=False,
dest='logging_on',
help='Activate the logging')
results = parser.parse_args()
You can use the logging_on to test and output values later on in your code (replace it by what makes sense for you). You can also use either a config file or/and an argument for the file log path.