Автоматическая регистрация "команд" для программы командной строки в Python - PullRequest
2 голосов
/ 10 января 2011

Я хотел бы разработать программу командной строки, которая может обрабатывать и предоставлять «помощь» для подкоманд. Если говорить конкретно, скажем, у меня есть один скрипт с именем «cgent», и я хотел бы, чтобы подкоманды «abc», «def» и «xyz» выполнялись и принимали остальные sys.args для обработки с помощью optparse.

cgent abc [options] 
cgent help abc
....

Все это просто, если я жестко закодирую имена подкоманд. Тем не менее, я хотел бы иметь возможность продолжать добавлять подкоманды, добавляя класс или модуль (?). Это похоже на идею, которая используется веб-фреймворками для добавления контроллеров, например. Я пробовал копаться в пилонах, чтобы посмотреть, смогу ли я воссоздать то, что там делается, но я не раскрыл логику. Любые предложения о том, как это сделать?

Спасибо, Шон

Ответы [ 2 ]

3 голосов
/ 10 января 2011

Если вам не нужно выполнять сложный анализ аргументов, я рекомендую модуль baker . Это позволяет вам определять подкоманды и их аргументы через декораторы. Например:

#!/usr/bin/env python
import baker

@baker.command()
def foo(a=1):
    print 'foo:', a

@baker.command()
def baz(b=1):
    print 'baz:', b

baker.run()

определяет две подкоманды foo и baz с (необязательными) параметрами a и b. Таким образом, вы можете использовать их так:

$ ./test_baker.py foo --a 2
foo: 2
$ ./test_baker.py baz
baz: 1

Он также использует строки документации для генерации справки.

Поскольку модуль baker является глобальным, ваши подкоманды могут охватывать несколько файлов .py. Пока они импортируются, подкоманды будут автоматически регистрироваться.

Более того, это всего лишь один .py файл, так что вы можете просто поместить его в дерево исходных текстов.

1 голос
/ 10 января 2011

Вам нужно будет создать «реестр команд».Это может быть просто словарь.

В основной программе вы делаете:

commands = {}

И в любых добавляемых вами подмодулях вы делаете

from yourmodule.main import commands

def mynewcommand(arguments=here):
    pass

commands['newcommand'] = mynewcommand

Тогда выможно использовать argparse для обработки команд.В этом случае ваш модуль должен добавить часть подпарамера для команды тоже.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...