Проверьте, установлен ли дополнительный аргумент argparse.
Я хотел бы проверить, был ли задан опциональный аргумент argparse пользователем или нет.
Можно ли безопасно проверять использование isset?
Что-то вроде этого:
if(isset(args.myArg)):
#do something
else:
#do something else
Означает ли это то же самое для аргументов типа float/int/string?
Я могу установить параметр по умолчанию и проверить его (например, установить myArg = -1 или "для строки или" NOT_SET"). Однако значение, которое я в конечном счете хочу использовать, вычисляется позже в script. Поэтому я бы установил его как -1 по умолчанию, а затем обновил его до другого. Это кажется немного неуклюжим по сравнению с просто проверкой того, было ли значение задано пользователем.
Ответы
Ответ 1
Я думаю, что необязательные аргументы (заданные с помощью --
) инициализируются на None
, если они не указаны. Таким образом, вы можете протестировать с помощью is not None
. Попробуйте пример ниже:
import argparse as ap
def main():
parser = ap.ArgumentParser(description="My Script")
parser.add_argument("--myArg")
args, leftovers = parser.parse_known_args()
if args.myArg is not None:
print "myArg has been set (value is %s)" % args.myArg
Ответ 2
Как отмечает @Honza is None
, это хороший тест. Это по умолчанию default
, и пользователь не может дать вам строку, которая дублирует ее.
Вы можете указать еще один default='mydefaultvalue
и проверить это. Но что, если пользователь указывает эту строку? Это считается установкой или нет?
Вы также можете указать default=argparse.SUPPRESS
. Тогда, если пользователь не использует этот аргумент, он не появится в пространстве имен args
. Но тестирование может быть более сложным:
args.foo # raises an AttributeError
hasattr(args, 'foo') # returns False
getattr(args, 'foo', 'other') # returns 'other'
Внутренне parser
хранит список seen_actions
и использует его для тестирования "обязательно" и "взаимно-исключая". Но он не доступен вам на стороне parse_args
.
Ответ 3
Если ваш аргумент является позиционным (т.е. он не имеет префикса "-" или "-", просто аргумент, как правило, имя файла), вы можете использовать параметр nargs, чтобы сделать это:
parser = argparse.ArgumentParser(description='Foo is a program that does things')
parser.add_argument('filename', nargs='?')
args = parser.parse_args()
if args.filename is not None:
print('The file name is {}'.format(args.filename))
else:
print('Oh well ; No args, no problems')
Ответ 4
Вот мое решение, если я использую переменную argparse
import argparse
ap = argparse.ArgumentParser()
ap.add_argument("-1", "--first", required=True)
ap.add_argument("-2", "--second", required=True)
ap.add_argument("-3", "--third", required=False)
# Combine all arguments into a list called args
args = vars(ap.parse_args()
if args["third"] is not None:
# do something
Это может дать более глубокое понимание вышеупомянутого ответа, который я использовал и адаптировал для работы в своей программе.
Ответ 5
Вы можете проверить необязательно прошедший флаг с параметрами действия store_true
и store_false
:
import argparse
argparser = argparse.ArgumentParser()
argparser.add_argument('-flag', dest='flag_exists', action='store_true')
print argparser.parse_args([])
# Namespace(flag_exists=False)
print argparser.parse_args(['-flag'])
# Namespace(flag_exists=True)
Таким образом, вам не нужно беспокоиться о проверке условным is not None
. Вы просто проверяете True
или False
. Подробнее об этих параметрах читайте в документах здесь
Ответ 6
Я думаю, что использование опции default=argparse.SUPPRESS
имеет смысл. Затем вместо проверки аргумента not None
проверяется, является ли аргумент in
результирующим пространством имен.
Пример:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--foo", default=argparse.SUPPRESS)
ns = parser.parse_args()
print("Parsed arguments: {}".format(ns))
print("foo in namespace?: {}".format("foo" in ns))
Использование:
$ python argparse_test.py --foo 1
Parsed arguments: Namespace(foo='1')
foo in namespace?: True
Аргумент не предоставляется:
$ python argparse_test.py
Parsed arguments: Namespace()
foo in namespace?: False