带参数的Python水泥子命令

时间:2017-01-31 02:12:20

标签: python

我正在使用Python水泥框架并尝试创建一个包含多个子命令的应用程序,每个子命令都有自己的参数。

Diving Right In示例显示了如何创建子命令,但这些子命令都没有自己的参数。

Argument and Options Handling示例显示了如何处理参数,但不显示子命令。

Application Controllers页面再次显示如何创建子命令,但没有专门针对子命令的参数。

Multiple Stacked Controllers非常接近,但我发现我无法让它看起来很正确。这就是我所拥有的:

from cement.core.foundation import CementApp
from cement.core.controller import CementBaseController, expose


class MyBaseController(CementBaseController):
    class Meta:
        label = 'base'
        description = "<Overall application description>"


class MySubcommand(CementBaseController):
    class Meta:
        label = 'subcommand1'
        stacked_on = 'base'
        stacked_type = 'nested'
        description = '<Subcommand description>'
        arguments = [(['--bar'], {'help': 'An option visible only to subcommand1!'})]

    @expose(help='<Redundant subcommand description')
    def subcommand1(self):
        self.app.log.info("This is what happens when you run demo2.py subcommand1")


class MyApp(CementApp):
    class Meta:
        label = 'demo2'
        base_controller = 'base'
        handlers = [MyBaseController, MySubcommand]


with MyApp() as app:
    app.run()

这样可行,但唯一的问题是提供的帮助文本很难:

> python3 demo2.py subcommand1 --help
usage: demo2 (sub-commands ...) [options ...] {arguments ...}

<Subcommand description>

commands:

  subcommand1
    <Redundant subcommand description

optional arguments:
  -h, --help  show this help message and exit
  --debug     toggle debug output
  --quiet     suppress all output
  --bar BAR   An option visible only to subcommand1!

如您所见,subcommand1是subcommand1的另一个子命令,带有冗余帮助文本。即使我省略了expose help参数,也会出现令人困惑的演示文稿。

如果我使用stacked_type = 'embedded'代替,那么教子命令的参数对所有其他命令都是可见的。

3 个答案:

答案 0 :(得分:2)

您应该考虑使用ArgparseController扩展程序中的新argparse(水泥附带)。它取代了CementBaseController,它将在水泥3中完全消失。ArgparseController更不容易定制,并且更加偏向......所以更多的是直接使用Argparse(即嵌套的子命令/控制器实际上是嵌套的子分析器,具有自己的参数等。)

水泥2没有删除CementBaseController或使ArgparseController成为默认值以保持兼容性,但可以从扩展程序获得,建议使用它。

答案 1 :(得分:1)

以下是基于@derks答案的示例。 ArgParseController显然是处理事情的新方法。

from cement.core.foundation import CementApp
from cement.ext.ext_argparse import ArgparseController, expose


class MyBaseController(ArgparseController):
    def default(self):
        self.app.args.print_help()

    @expose(
        arguments=[
            (['a'], {'help': 'A positional argument'}),
            (['--barg', '-b'], {'help': 'Keyword argument'}),
        ],
        help='<Subcommand description>')
    def subcommand(self):
        self.app.log.info("subcommand successful")


class MyApp(CementApp):
    class Meta:
        label = 'demo'
        handlers = [MyBaseController]


with MyApp() as app:
    app.run()

旧答案

这是我的原始答案,基本上是使用CementBaseController

的kludge

expose hide option可以产生一些漂亮的帮助文字:

from cement.core.foundation import CementApp
from cement.core.controller import CementBaseController, expose


class MyBaseController(CementBaseController):
    class Meta:
        label = 'base'
        description = "<Overall application description>"


class MySubcommand(CementBaseController):
    class Meta:
        label = 'subcommand1'
        stacked_on = 'base'
        stacked_type = 'nested'
        description = '<Subcommand description>'
        arguments = [(['--bar'], {'help': 'An option visible only to subcommand1!'})]

    @expose(hide=True)
    def default(self):
        self.app.log.info("This is what happens when you run demo2.py subcommand1")


class MyApp(CementApp):
    class Meta:
        label = 'demo3'
        base_controller = 'base'
        handlers = [MyBaseController, MySubcommand]


with MyApp() as app:
    app.run()

帮助文字:

> python3 demo3.py subcommand1 --help
usage: demo3 (sub-commands ...) [options ...] {arguments ...}

<Subcommand description>

optional arguments:
  -h, --help  show this help message and exit
  --debug     toggle debug output
  --quiet     suppress all output
  --bar BAR   An option visible only to subcommand1!

答案 2 :(得分:-1)

有没有显示--help子命令的方法吗?

begin
  for rec in (select expression from mytable where code = :code) loop
    execute immediate 'insert into other_table ' || rec.expression;
    commit;
  end loop;
end;

显示相同的内容

`python3 demo3.py subcommand1`