Python argparse - либо оба необязательных аргумента, либо ни один
У меня есть программа, которая использует имя и пароль по умолчанию. Я использую argparse, чтобы позволить пользователю указывать параметры командной строки, и я хотел бы включить пользователя для предоставления программе другого имени и пароля для использования. Поэтому у меня есть следующее:
parser.add_argument(
'-n',
'--name',
help='the login name that you wish the program to use'
)
parser.add_argument(
'-p',
'--password',
help='the password to log in with.'
)
Но не имеет смысла указывать только имя или только пароль, но было бы бессмысленно указывать ни один. Я заметил, что у argparse есть возможность указать, что два аргумента являются взаимоисключающими. Но у меня есть два аргумента, которые должны появиться вместе. Как мне получить это поведение? (Я нашел "группы аргументов", упомянутые в документах, но они, похоже, не решают мою проблему http://docs.python.org/2/library/argparse.html#argument-groups)
Ответы
Ответ 1
Я считаю, что лучший способ справиться с этим - это обработать возвращаемое пространство имен. Причина, по которой argparse
не поддерживает это, состоит в том, что она анализирует аргументы 1 за раз. Легко для argparse
проверить, не было ли что-то уже разобрано (вот почему работают взаимоисключающие аргументы), но нелегко понять, будет ли что-то разбираться в будущем.
Прост:
parser.add_argument('-n','--name',...,default=None)
parser.add_argument('-p','--password',...,default=None)
ns = parser.parse_args()
if len([x for x in (ns.name,ns.password) if x is not None]) == 1:
parser.error('--name and --password must be given together')
name = ns.name if ns.name is not None else "default_name"
password = ns.password if ns.password is not None else "default_password"
похоже, что этого будет достаточно.
Ответ 2
Я знаю, что прошло уже более двух лет, но я нашел хороший и лаконичный способ сделать это:
if bool(ns.username) ^ bool(ns.password):
parser.error('--username and --password must be given together')
^
- это оператор XOR в Python. Требовать, чтобы оба аргумента, заданные в командной строке, были в основном тестом XOR.
Ответ 3
Скорее всего, я это сделаю. Поскольку у вас есть существующие значения по умолчанию с возможностью изменения, определите значения по умолчанию, но не используйте их в качестве аргументов по умолчанию:
default_name = "x"
default_pass = "y"
parser.add_argument(
'-n',
'--name',
default=None,
help='the login name that you wish the program to use'
)
parser.add_argument(
'-p',
'--password',
default=None,
help='the password to log in with.'
)
args = parser.parse_args()
if all(i is not None for i in [args.name, args.password]):
name = args.name
passwd = args.password
elif any(i is not None for i in [args.name, args.password]):
parser.error("Both Name and Password are Required!")
else:
name = default_name
passwd = default_pass