我正在使用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'
代替,那么教子命令的参数对所有其他命令都是可见的。
答案 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
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`