Cemre Mengü
Cemre Mengü

Reputation: 18754

Having options in argparse with a dash

I want to have some options in argparse module such as --pm-export however when I try to use it like args.pm-export I get the error that there is not attribute pm. How can I get around this issue? Is it possible to have - in command line options?

Upvotes: 257

Views: 108120

Answers (6)

Thomas Orozco
Thomas Orozco

Reputation: 55197

From the argparse docs:

For optional argument actions, the value of dest is normally inferred from the option strings. ArgumentParser generates the value of dest by taking the first long option string and stripping away the initial -- string. Any internal - characters will be converted to _ characters to make sure the string is a valid attribute name.

So you should be using args.pm_export.

Upvotes: 379

georg
georg

Reputation: 214959

Dashes are converted to underscores:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo-bar')
args = parser.parse_args(['--foo-bar', '24'])
print(args)  # Namespace(foo_bar='24')

Upvotes: 30

seriyPS
seriyPS

Reputation: 7102

Unfortunately, dash-to-underscore replacement doesn't work for positional arguments (arguments not prefixed by --). For example:

import argparse
import sys

parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument('logs-dir',
                    help='Directory with .log and .log.gz files')
parser.add_argument('results-csv', type=argparse.FileType('w'),
                    default=sys.stdout,
                    help='Output .csv filename')
args = parser.parse_args()

print(args)
# Namespace(**{'logs-dir': './', 'results-csv': <_io.TextIOWrapper name='mydata.csv' mode='w' encoding='UTF-8'>})

So, you should use the first argument to add_argument() for the attribute name and pass a metavar kwarg to set how it should be displayed in help:

parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument('logs_dir', metavar='logs-dir',
                    help='Directory with .log and .log.gz files')
parser.add_argument('results_csv', metavar='results-csv',
                    type=argparse.FileType('w'),
                    default=sys.stdout,
                    help='Output .csv filename')
args = parser.parse_args()

print(args)
# Namespace(logs_dir='./', results_csv=<_io.TextIOWrapper name='mydata.csv' mode='w' encoding='UTF-8'>)

Upvotes: 171

eternalodballl
eternalodballl

Reputation: 240

I guess the last option is to change shorten option -a to --a

import argparse

parser = argparse.ArgumentParser(description="Help")
parser.add_argument("--a", "--argument-option", metavar="", help="")   # change here
args = parser.parse_args()
option = args.a                # And here
print(option)

Upvotes: -1

Denis The Menace
Denis The Menace

Reputation: 500

Concise and explicit but probably not always acceptable way would be to use vars():

#!/usr/bin/env python3

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('a-b')
args = vars(parser.parse_args())

print(args['a-b'])

Upvotes: 4

getattr(args, 'positional-arg')

This is another OK workaround for positional arguments:

#!/usr/bin/env python3

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('a-b')
args = parser.parse_args(['123'])
assert getattr(args, 'a-b') == '123'

Tested on Python 3.8.2.

Upvotes: 3

Related Questions