Установка параметров из переменных среды в позиционные аргументы при использовании argparse
У меня есть небольшая программа, которая использует argparse и позиционный аргумент. Я пытаюсь разрешить этот аргумент с помощью переменной окружения, но не работаю.
Я видел этот пост: установка параметров из переменных окружения при использовании argparse, в котором упоминается та же проблема, но не для позиционных аргументов.
Это код до сих пор:
import argparse
import os
class EnvDefault(argparse.Action):
def __init__(self, envvar, required=True, default=None, **kwargs):
if not default and envvar:
if envvar in os.environ:
default = os.environ[envvar]
if required and default:
required = False
super(EnvDefault, self).__init__(default=default, required=required, **kwargs)
def __call__(self, parser, namespace, values, option_string=None):
setattr(namespace, self.dest, values)
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('testvar', help="Test variable", action=EnvDefault, envvar='TEST_VAR')
parser.add_argument('--othervar', help="Other variable", action='store_true')
args = parser.parse_args()
if not args.testvar: exit(parser.print_usage())
print args.testvar
Который возвращает это:
$ TEST_VAR="bla" ./test.py
usage: test.py [-h] [--othervar] testvar
test.py: error: too few arguments
2 ответа
too few
Сообщение об ошибке указывает, что у вас есть немного более старая версия Python / argparse. Вот код, который генерирует сообщение. Это происходит в конце разбора:
# if we didn't use all the Positional objects, there were too few
# arg strings supplied.
if positionals:
self.error(_('too few arguments'))
# make sure all required actions were present
for action in self._actions:
if action.required:
if action not in seen_actions:
name = _get_action_name(action)
self.error(_('argument %s is required') % name)
positionals
запускает список всех позиционных аргументов, которые удаляются при сопоставлении со строками аргументов. Так что это тестирование, если таковые не были сопоставлены.
Обратите внимание, что тест required
Атрибут появляется после этого позиционного теста, поэтому его изменение, как и ваше действие, не помогает.
Единственный способ сделать позиционный опциональный nargs
-? или же *. Пустой список строк соответствует этим, поэтому такой позиционный всегда используется. Проверьте документы для них. const
Параметр может быть полезен.
Последняя версия падает, что if positionals
проверить, используя только required
Тест для создания списка аргументов, которые не были использованы. Ваше специальное действие может работать в этом коде.
Вы должны сделать позиционный аргумент необязательным, попробуйте nargs='?'
:
...
parser.add_argument('testvar', help="Test variable", action=EnvDefault,
envvar='TEST_VAR', nargs='?')
...
Обратите внимание, что выходные данные немного изменяются:
$ python test.py
usage: test.py [-h] [--othervar] [testvar]
Примечание: есть один побочный эффект - он не возвращает ошибку, даже если переменная env не установлена.