2010-12-06 5 views
2

Я использую Argparser для обработки аргументов для моей прошивки CLI. Но по прошествии времени я думаю, что это не очень хорошая идея. Здесь возникает проблема. Я хочу использовать параметры без символа префикса. Подобно git commit или svn move. Я немного искал и обнаружил, что у Argparse есть метод add_subparser(). Давайте заселить наш Foo прогу:Есть ли способ установить параметры без префикса в Argparser?

parser = argparse.ArgumentParser(prog='foo', usage='%(prog)s [options]') 

subparsers = parser.add_subparsers(help='sub-command help') 
parser_a = subparsers.add_parser('add', help='a help') 
parser_a.add_argument('-ap', '--add-project', 
        nargs='*', 
        action='store', 
        help="Add project") 

parser_d = subparsers.add_parser('del', help='a help') 
parser_d.add_argument('-dp', '--delete-project', 
        nargs='*', 
        action='store', 
        help="Delete project") 

args = parser.parser_args() 

Пусть теперь выполнить Foo с опциями и печати args имен (я не сделал в прошлом весь код, вы получите точку):

$ ./foo del 
Namespace(delete_project=None) 
$ ./foo add 
Namespace(add_project=None) 

Как вы видите, если я исполню опцию del, , то добавление_проекта не передается переменной args. Это вызывает проблемы, если у меня есть «если условие» в моей главной функции() как

def main(args): 

    if args.delete_project: 
     ... 
    if args.add_project: 
     ... 

Я получаю исключение AttributeError, что пространство имен не имеет атрибута с именем add_project если я исполняю ./foo del. Кроме того, я не могу передать какие-либо аргументы опциям del и add. Я также установил prefix_chars в пустую строку, которая тоже не работала.

Что такое способ его обработки? Является ли argparse способным создавать такие параметры, как git, svn и т. Д., Или я должен создать свою собственную функцию и самостоятельно обрабатывать все аргументы?

ответ

0

Вместо того, чтобы ваш, если заявления, the argparse docs recommend something like this:

parser_X.set_defaults(action=action_func) 
args.action(args) 

Тогда add_action будет смотреть на add_project и del_action в del_project.

+0

Это абсолютно так.OP получает ошибки атрибутов на подпараметрах, которые пользователь не вызывал, и я объяснил ему, как смотреть на подпараметр, который был фактически использован. – Tobu

+0

Ба, моя ошибка, я полностью пропустил 'subparser'. –

+0

@ Ник Хе. Это было немного немного, я оставляю объяснение. – Tobu

0

Edit: Видимо по умолчанию для default является None, что означает, что мы не один, так что вы должны будете использовать True и False (что правильный путь, так или иначе).

Вы должны добавить default, когда вы добавить свой аргумент анализатору:

parser_a.add_argument('-ap', '--add-project', 
        nargs = '*', 
        action = 'store_true', 
        default = False, 
        help = "Add project") 

Вы можете увидеть в документации по add_argument метода here. (Я понимаю, что макет документа argparse не самый лучший способ выяснить, как делать вещи, которые не вызваны в примерах).

Также, как Тобу соответствующим образом указывает в своем ответе, неиспользуемые подпункты не находят, t вызывается, поэтому вы не можете безопасно исследовать свои значения, не защищая, по крайней мере, свой код в блоке try:. Однако на самом деле вы должны использовать функциональные возможности связывания action с вашими подпараметрами, если у вас нет гораздо более сложной ситуации, когда необходимо разделить состояние.

+1

* Аргумент ключевого слова по умолчанию для add_argument(), значение по умолчанию которого равно None ... Это не решает эту проблему. Он по-прежнему не пропускает add_project, если я выполняю 'foo del' –

+0

@Farslan: Bah, поэтому действительно вы вынуждены использовать' True' и 'False' тогда (и, следовательно, действительно' store_true' и 'store_false' в вашем действии) –