Я не нахожу способ создать такую структуру аргументов с пакетом argparse
:
$ python3 prog.py [ A (a1 VAR | a2 | a3) | Б | C c]
Я бы хотел, чтобы A был корневым для семейства подкоманд, в моем случае это черный список (./prog blacklist [add PATH | rm | ...]), но мне также нужны две другие функции: $ ./prog push FILE
и наконец $ ./prog --interactive
.
Я уже серьезно посмотрел на argparse документацию .
Я пытался использовать add_mutually_exclusive_group()
для перегруппировки a1, b1 и c1, но я застрял с этим:
ValueError: mutually exclusive arguments must be optional
Мне удалось получить python3 prog.py (A a1 a2| B | C c1)
с использованием групп, но я либо что-то упустил, понял, либо в argparse
ничего не включено для этого случая.
Любая помощь будет принята с благодарностью. Спасибо за ваше время!
РЕДАКТИРОВАТЬ: Мне наконец удалось сделать то, что я искал. Однако я не уверен, что это очень чисто. Было бы здорово иметь несколько пакетов, которые делают это лучше, чем я.
Благодаря этому сайту я нашел способ достичь своей цели. Я прилагаю код, если когда-либо это кого-то интересует
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import argparse
from sys import argv
class CLI:
"""
Class which represent the CLI's behaviour.
Every function describes a subcommands tree and
how the CLI should respond.
"""
def __init__(self):
parser = argparse.ArgumentParser(
description='',
usage='''cli <command> [<args>]'
Commands list:
cli blacklist Interact with the blacklist.
cli interactive Run an interactive mode for queries.
cli read <path> Try to extract credentials.
'''
)
parser.add_argument('command', help='Subcommand to run')
# only parsing the subcommand
args = parser.parse_args(argv[1:2])
if not hasattr(self, args.command):
print('Unrecognized command')
parser.print_help()
exit(1)
# use dispatch pattern to invoke method with same name
getattr(self, args.command)()
def blacklist(self):
"""
Parser for blacklist methods.
"""
parser = argparse.ArgumentParser(
description='',
usage='''cli blacklist <subcommand> [<args>]
Subcommands list:
add <domain> Add <domain> from the blacklist.
export <path> Export blacklist as csv to <path>.
import <path> [-e] Import <path> as csv. Erase existing blacklist if -e.
remove <domain> Remove <domain> from the blacklist.
show Print the blacklist.
'''
)
parser.add_argument('subcommand')
args = parser.parse_args(argv[2:3])
if not hasattr(self, 'bl_%s' % (args.subcommand)):
print('Unrecognized command')
parser.print_usage()
exit(1)
getattr(self, 'bl_%s' % (args.subcommand))()
def bl_add(self):
print('add `%s` to the blacklist' % (argv[3:4][0]))
def bl_export(self):
print('export')
def bl_import(self):
print('import')
def bl_remove(self):
print('remove')
def bl_show(self):
print('show')
def read(self):
if len(argv) != 3:
print('Wrong number of arguments')
print('usage: cli read <path>')
exit(1)
print('process %s' % (argv[2:3][0]))
def interactive(self):
print('run interactive mode')
CLI()