This question already has answers here:
Using a python keyword as an option in argparse
(2 answers)
Closed 14 days ago.
When I try to get argument with flag "--from" from argparse.ArgumentParser.parse_args() an error occurs. IDE says that "from" is import statement and the code is unreachable:
parser = argparse.ArgumentParser(prog='cache_wiki.py',
description='Find shortest path between links')
parser.add_argument('--from', required=True, help='page to start search with')
args = parser.parse_args()
print(args.from)
It is ok with another name:
parser = argparse.ArgumentParser(prog='cache_wiki.py',
description='Find shortest path between links')
parser.add_argument('--f', required=True, help='page to start search with')
args = parser.parse_args()
print(args.f)
but I really need to use flag "--from".
I would ignore the IDE here. True, you cannot use args.from, but that's just a syntactic limitation. You can still access the attribute using, for example, getattr(args, 'from').
You can also override the default destination name so that you can use the option --from, but set a different attribute:
...
parser.add_argument('--from',
required=True,
dest='from_',
help='page to start search with')
args = p.parse_args(['--from', 'foo'])
assert args.from_ == 'foo'
Related
This question already has an answer here:
Python Argparse - Set default value of a parameter to another parameter
(1 answer)
Closed last year.
I would like to set an ArgumentParser argument value as the default value of another argument in the same parser.
Desired behavior:
parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormater)
parser.add_argument('-p', '--pin_file_path', help = "the directory of the given pin file", default=os.getcwd())
parser.add_argument('-o', '--other', help="", default=**pin_file_path!**)
parse_known_args parse the argument and send it to another argument.
pin_file_path= None
parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormater)
parser.add_argument('-p', '--pin_file_path', help = "the directory of the given pin file", default = os.getcwd())
args, remaining = parser.parse_known_args()
parser.add_argument('--option2', default=args.pin_file_path)
args = parser.parse_args()
I'm trying to parse commands with arguments using the python 3 Built-in argparse module.
I have read the argparse documentation partially, however, I could not find anything that meets my requirements.
I parse the arguments as input (I have my reasons).
I have multiple commands, for each, there are both essential and optional arguments.
For example:
restart --name (the name is replaced)
restart is the command and name is the essential argument.
Currently my code would count the "--" in the input and call the function with corresponding booleans (if --all given, is_all boolean parameter will be true)
I can also add an optional argument --all (all is not replaced).
Sounds like you are looking for something like this
def get_arguments():
parser = argparse.ArgumentParser()
parser.add_argument("--arg1", required=False, default=None)
parser.add_argument("--arg2", required=False, default=None)
return parser.parse_args()
args = get_arguments()
if args.arg1:
# do something
Really hard to answer this without seeing your code or example of what you want.
I'm assuming you're doing something like a shell of sorts. I'm going to also assume that each line entered has a command, each with their own arguments.
from argparse import ArgumentParser
def get_parser(cmd):
'''Returns a parser object for a given command'''
# Instantiate the parser object, add the appropriate arguments for the command
return parser # This is an example -- you need to instantiate it
def main():
while True:
try:
in_line = input('> ')
if not in_line.strip(): # Quit if empty
break
args = in_line.split()
parser = get_parser(args[0])
opts = parser.parser_args(args)
# Do stuff with opts depending on command
except EOFError:
break
except SystemExit:
pass # Prevent failures from killing the program by trapping sys.exit()
This question already has answers here:
Parsing boolean values with argparse
(26 answers)
Closed 1 year ago.
I ran my program using the below line
python ***.py --if_normalize False
but my program recognizes if_normalize variable to be True
def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument("--work-path", required=True, type=str)
parser.add_argument("--seed", default=42, type=int, help="Random seed")
parser.add_argument("--batch-size", default=128, type=int)
parser.add_argument("--attack", default='no', type=str)
parser.add_argument("--gpu",default=2, type=int)
parser.add_argument('--if_normalize', default=False, type=bool)
return parser.parse_args()
args = parse_args()
print(args)
and it prints if_normalize is True
I passed 'False, false, -1' but still it recognizes as True
Because it just runs the input through bool, and bool('False') is True, because any non-empty string is truthy.
You'd usually do this by using a flag instead:
parser.add_argument('--if-normalize', action='store_true')
The store_true action implies a default of False, and sets it to True if the flag is present. I.e. you'd use it like:
$ python ***.py --if-normalize
You should change to the following:
parser.add_argument('--if_normalize', action='store_true')
This will set the argument if_normalize to True when you add it to the command line arguments when calling to your script.
You can refer to the docs and see exactly what it does.
https://docs.python.org/3/library/argparse.html#type
The bool() function is not recommended as a type converter. All it does is convert empty strings to False and non-empty strings to True. This is usually not what is desired.
This type section was recently expanded in an attempt to remove some common misunderstandings, including this misuse of the bool (a builtin) function.
You could write your own function that parses a whole slew of 'yes/no' words. Developers have declined to do so because there are too many alternatives, especially if non-English possibilities are included.
The store_true Action is enough for most purposes.
I'm writing a simple script that will be used parse the contents of a JSON file stored on AWS CloudWatch. I've added an argument parser to the script that will accept user input, and allow the user to either print the output of the file to the screen (in a predetermined fashion), or allow them to output the contents to a local JSON file. Here's a snippet of what's stumping me:
import argparse
parser = argparse.ArgumentParser(description="Process a log file")
parser.add_argument('-o', '--output', choices=[???, 'print'],
default='print', help='Specify logfile output path or print to screen')
args = parser.parse_args()
My question stems from the parser.add_argument line, specifically the choices argument. I'd like to allow two inputs for this flag, those being either print or some valid path on their local machine. I'd like the choice that's currently marked by question marks to be a PATH that Python can recognize.
Is there a way, using argparse, to specify that one of of the arguments to a flag must be a PATH? Search results have been, so far, inconclusive.
Thanks in advance!
Use the type keyword argument to add_argument, instead of choices. As the documentation says:
The type keyword argument of add_argument() allows any necessary
type-checking and type conversions to be performed.
def myfiletype(arg):
if arg == 'print' or os.path.isdir(arg):
return arg
else:
raise ValueError('Invalid path specification')
parser.add_argument('-o', '--output', type=myfiletype,
default='print',
help='Specify logfile output path or print to screen')
Define a custom type (as in https://stackoverflow.com/a/14117511/1093967), where the value can be a valid path or 'print'. choices isn't the right choice here.
I am trying to make a Python program that uses the argparse module to parse command-line options.
I want to make an optional argument that can either be named or positional. For example, I want myScript --username=batman to do the same thing as myScript batman. I also want myScript without a username to be valid. Is this possible? If so, how can it be done?
I tried various things similar to the code below without any success.
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.add_argument("-u", "--user-name", default="admin")
group.add_argument("user-name", default="admin")
args = parser.parse_args()
EDIT: The above code throws an exception saying ValueError: mutually exclusive arguments must be optional.
I am using Python 2.7.2 on OS X 10.8.4.
EDIT: I tried Gabriel Jacobsohn's suggestion but I couldn't get it working correctly in all cases.
I tried this:
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.add_argument("-u", "--user-name", default="admin", nargs="?")
group.add_argument("user_name", default="admin", nargs="?")
args = parser.parse_args()
print(args)
and running myScript batman would print Namespace(user_name='batman'), but myScript -u batman and myScript --user-name=batman would print Namespace(user_name='admin').
I tried changing the name user-name to user_name in the 1st add_argument line and that sometimes resulted in both batman and admin in the namespace or an error, depending on how I ran the program.
I tried changing the name user_name to user-name in the 2nd add_argument line but that would print either Namespace(user-name='batman', user_name='admin') or Namespace(user-name='admin', user_name='batman'), depending on how I ran the program.
The way the ArgumentParser works, it always checks for any trailing positional arguments after it has parsed the optional arguments. So if you have a positional argument with the same name as an optional argument, and it doesn't appear anywhere on the command line, it's guaranteed to override the optional argument (either with its default value or None).
Frankly this seems like a bug to me, at least when used in a mutually exclusive group, since if you had specified the parameter explicitly it would have been an error.
That said, my suggested solution, is to give the positional argument a different name.
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.add_argument('-u','--username')
group.add_argument('static_username',nargs='?',default='admin')
Then when parsing, you use the optional username if present, otherwise fallback to the positional static_username.
results = parser.parse_args()
username = results.username or results.static_username
I realise this isn't a particularly neat solution, but I don't think any of the answers will be.
Here is a solution that I think does everything you want:
import argparse
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument("-u", "--user-name", default="admin")
# Gather all extra args into a list named "args.extra"
parser.add_argument("extra", nargs='*')
args = parser.parse_args()
# Set args.user_name to first extra arg if it is not given and len(args.extra) > 0
if args.user_name == parser.get_default("user_name") and args.extra:
args.user_name = args.extra.pop(0)
print args
If you run myScript -u batman or myScript --user-name=batman, args.user_name is set to 'batman'. If you do myScript batman, args.user_name is again set to 'batman'. And finally, if you just do myScript, args.user_name is set to 'admin'.
Also, as an added bonus, you now have all of the extra arguments that were passed to the script stored in args.extra. Hope this helps.
Try to use the "nargs" parameter of the add_argument method.
This way it works for me.
Now you can add the username twice,
so you have to check it and raise an error, if you want.
import argparse
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument("-u", "--user-name", default="admin")
parser.add_argument("user_name", default="admin", nargs="?")
args = parser.parse_args()
print(args)