Мой вариант использования — несколько необязательных позиционных аргументов, взятых из ограниченного набора вариантов, со значением по умолчанию, которое представляет собой список, содержащий два из этих вариантов. Я не могу изменить интерфейс из-за проблем с обратной совместимостью. Мне также необходимо поддерживать совместимость с Python 3.4.
Вот мой код. Как видите, я хочу, чтобы по умолчанию использовался список из двух значений из набора вариантов.
parser = argparse.ArgumentParser()
parser.add_argument('tests', nargs='*', choices=['a', 'b', 'c', 'd'],
default=['a', 'd'])
args = parser.parse_args()
print(args.tests)
Все верно:
$ ./test.py a
['a']
$ ./test.py a d
['a', 'd']
$ ./test.py a e
usage: test.py [-h] [{a,b,c,d} ...]
test.py: error: argument tests: invalid choice: 'e' (choose from 'a', 'b', 'c', 'd')
Это неверно:
$ ./test.py
usage: test.py [-h] [{a,b,c,d} ...]
test.py: error: argument tests: invalid choice: ['a', 'd'] (choose from 'a', 'b', 'c', 'd')
Я нашел МНОГО подобных вопросов, но ни один из них не касался этого конкретного варианта использования. Самое многообещающее предложение, которое я нашел (в другом контексте), - это написать собственное действие и использовать его вместо вариантов:
Это не идеально. Я надеюсь, что кто-нибудь подскажет мне вариант, который я пропустил.
Вот обходной путь, который я планирую использовать, если нет:
parser.add_argument('tests', nargs='*',
choices=['a', 'b', 'c', 'd', 'default'],
default='default')
Мне разрешено добавлять аргументы, если я поддерживаю обратную совместимость.
Спасибо!
Обновление: в итоге я выбрал настраиваемое действие. Я сопротивлялся, потому что это не похоже на вариант использования, который требует чего-то специального. Тем не менее, это более или менее похоже на предполагаемый вариант использования подкласса argparse.Action, и это делает намерение очень явным и дает самый чистый результат, ориентированный на пользователя, который я нашел.
class TestsArgAction(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
all_tests = ['a', 'b', 'c', 'd']
default_tests = ['a', 'd']
if not values:
setattr(namespace, self.dest, default_tests)
return
# If no argument is specified, the default gets passed as a
# string 'default' instead of as a list ['default']. Probably
# a bug in argparse. The below gives us a list.
if not isinstance(values, list):
values = [values]
tests = set(values)
# If 'all', is found, replace it with the tests it represents.
# For reasons of compatibility, 'all' does not actually include
# one of the tests (let's call it 'e'). So we can't just do
# tests = all_tests.
try:
tests.remove('all')
tests.update(set(all_tests))
except KeyError:
pass
# Same for 'default'
try:
tests.remove('default')
tests.update(set(default_tests))
except KeyError:
pass
setattr(namespace, self.dest, sorted(list(tests)))
Подробнее здесь: https://stackoverflow.com/questions/733 ... nd-default
Есть ли способ использовать Python argparse с nargs='*', выбором и значением по умолчанию? ⇐ Python
Программы на Python
1766522081
Anonymous
Мой вариант использования — несколько необязательных позиционных аргументов, взятых из ограниченного набора вариантов, со значением по умолчанию, которое представляет собой список, содержащий два из этих вариантов. Я не могу изменить интерфейс из-за проблем с обратной совместимостью. Мне также необходимо поддерживать совместимость с Python 3.4.
Вот мой код. Как видите, я хочу, чтобы по умолчанию использовался список из двух значений из набора вариантов.
parser = argparse.ArgumentParser()
parser.add_argument('tests', nargs='*', choices=['a', 'b', 'c', 'd'],
default=['a', 'd'])
args = parser.parse_args()
print(args.tests)
Все верно:
$ ./test.py a
['a']
$ ./test.py a d
['a', 'd']
$ ./test.py a e
usage: test.py [-h] [{a,b,c,d} ...]
test.py: error: argument tests: invalid choice: 'e' (choose from 'a', 'b', 'c', 'd')
Это неверно:
$ ./test.py
usage: test.py [-h] [{a,b,c,d} ...]
test.py: error: argument tests: invalid choice: ['a', 'd'] (choose from 'a', 'b', 'c', 'd')
Я нашел МНОГО подобных вопросов, но ни один из них не касался этого конкретного варианта использования. Самое многообещающее предложение, которое я нашел (в другом контексте), - это написать собственное действие и использовать его вместо вариантов:
[list]
[*]https://stackoverflow.com/a/8624107/7660197
[/list]
Это не идеально. Я надеюсь, что кто-нибудь подскажет мне вариант, который я пропустил.
Вот обходной путь, который я планирую использовать, если нет:
parser.add_argument('tests', nargs='*',
choices=['a', 'b', 'c', 'd', 'default'],
default='default')
Мне разрешено добавлять аргументы, если я поддерживаю обратную совместимость.
Спасибо!
Обновление: в итоге я выбрал настраиваемое действие. Я сопротивлялся, потому что это не похоже на вариант использования, который требует чего-то специального. Тем не менее, это более или менее похоже на предполагаемый вариант использования подкласса argparse.Action, и это делает намерение очень явным и дает самый чистый результат, ориентированный на пользователя, который я нашел.
class TestsArgAction(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
all_tests = ['a', 'b', 'c', 'd']
default_tests = ['a', 'd']
if not values:
setattr(namespace, self.dest, default_tests)
return
# If no argument is specified, the default gets passed as a
# string 'default' instead of as a list ['default']. Probably
# a bug in argparse. The below gives us a list.
if not isinstance(values, list):
values = [values]
tests = set(values)
# If 'all', is found, replace it with the tests it represents.
# For reasons of compatibility, 'all' does not actually include
# one of the tests (let's call it 'e'). So we can't just do
# tests = all_tests.
try:
tests.remove('all')
tests.update(set(all_tests))
except KeyError:
pass
# Same for 'default'
try:
tests.remove('default')
tests.update(set(default_tests))
except KeyError:
pass
setattr(namespace, self.dest, sorted(list(tests)))
Подробнее здесь: [url]https://stackoverflow.com/questions/73396488/is-there-a-way-to-use-python-argparse-with-nargs-choices-and-default[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия