Проверьте, установлен ли необязательный аргумент argparse


Я хотел бы проверить, был ли необязательный аргумент argparse установлен пользователем или нет.

могу ли я безопасно проверить с помощью isset?

что-то вроде этого:

if(isset(args.myArg)):
    #do something
else:
    #do something else

работает ли это одинаково для аргументов типа float / int / string?

Я мог бы установить параметр по умолчанию и проверить его (например, установить myArg = -1, или "" для строки, или "NOT_SET"). Однако значение, которое я в конечном итоге хочу использовать, вычисляется только позже в скрипте. Так Что Я было бы установить его в -1 по умолчанию, а затем обновить его до чего-то еще позже. Это кажется немного неуклюжим по сравнению с простой проверкой, если значение было установлено пользователем.

6 58

6 ответов:

Я думаю, что необязательные аргументы (указан с --) инициализируются 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

как отмечает @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, и использует его для "необходимого" и "mutually_exclusive" тестирования. Но это не доступно для вас внеparse_args.

Если ваш аргумент позиционные (т. е. у него нет префикса "-" или"--", только аргумент, обычно имя файла), то вы можете использовать параметр 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')

вы можете проверить необязательно переданный флаг с 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. Подробнее об этих параметрах читайте в документации здесь

Я думаю, используя опцию 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

вот мое решение, чтобы увидеть, если я использую переменную 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

Это может дать более глубокое представление о приведенном выше ответе, который я использовал и адаптировал для работы в моей программе.