Мне нужно обработать два способа настройки приложения. Один из них - через аргументы командной строки, а другой - из файла JSON (на самом деле файл JSON является результатом хранения аргументов из предыдущего запуска).
Я могу справиться с этим путем объединения двух пространств именобъекты, что-то вроде этого:
cli_args = some_parser.parse_args()
with open(json_file, 'r') as f:
json_args = json.load(f)
all_args = argparse.Namespace()
all_args.__dict__ = {**vars(cli_args), **json_args}
# or all_args.__dict__ = {**json_args, **vars(cli_args)}
Проблема в последней строке. Если я выберу первую версию, аргументы из файла JSON будут иметь приоритет. Если я выберу вторую версию, аргументы из CLI будут иметь приоритет.
Я бы хотел, чтобы аргументы CLI имели приоритет, , но только , если они действительно были указаны. Проблема возникает, когда анализатор допускает значения по умолчанию. В этом случае объект cli_args
будет заполнен значениями по умолчанию, и это будет иметь приоритет над аргументами JSON.
Для простого примера, давайте возьмем этот синтаксический анализатор:
parser = argparse.ArgumentParser()
parser.add_argument('--foo', default='FOO')
parser.add_argument('--bar', default='BAR')
* 1015Скажем, у меня есть файл JSON с
{
"foo": "myfoo",
"bar": "mybar"
}
, и я вызываю мое приложение с помощью python myapp.py --foo hello
.
Я хотел бы получить объект пространства имен, имеющий foo=hello, bar=mybar
. Оба способа объединения аргументов дадут что-то другое. Во-первых, если я предоставлю приоритет JSON-файлу, я получу foo=myfoo, bar=mybar
. Если я даю CLI приоритет, я получаю foo=hello, bar=BAR
.
Проблема заключается в том, что я не вижу способа определить, какие аргументы в пространстве имен, возвращенные из parser.parse_args()
, были заполнены пользователем, а какиебыли заполнены с использованием настроек по умолчанию.
Есть ли способ задать argparse, какие аргументы фактически были явно заданы в командной строке, а не заполнены значениями по умолчанию?