通过内省实现命令行参数解析

5
我正在开发一个管理脚本,需要通过大量的命令行选项来完成。最初几个版本的脚本使用optparse收集用户输入,然后按照适当的顺序测试每个选项的值,并执行相应的操作。这导致了一堆难以阅读和维护的代码。
我正在寻找更好的解决方案。
我的希望是创建一个系统,在其中可以以更正常的Python方式编写函数,然后在运行脚本时,从我的函数生成选项(和帮助文本),解析并按适当的顺序执行。此外,我真的很想能够构建类似Django风格的子命令接口,其中“myscript.py install”与“myscript.py remove”完全分离(不同的选项、帮助等)。
我找到了simon willison's optfunc,它做了很多这方面的工作,但似乎没有达到预期——我想将每个选项都作为一个函数来编写,而不是试图将整个选项集压缩成一个巨大的选项字符串。
我想象一种涉及主要功能类集合的架构,每个类的定义方法对应于命令行中的特定选项。这种结构的优点是每个选项都与其修改的功能代码紧密相连,易于维护。我不确定如何处理命令的排序,因为类方法的排序是不确定的。
在重新发明轮子之前:是否有其他现有的代码片段表现类似?其他易于修改的东西?提问已经澄清了我自己的想法,但欢迎反馈为什么这是一个糟糕的想法,或者它应该如何工作。
2个回答

4

不要把时间浪费在“内省”上。

每个“Command”或“Option”都是一个带有两组方法函数或属性的对象。

  1. 向optparse提供设置信息。

  2. 实际执行工作。

这是所有命令的超类。

class Command( object ):
    name= "name"
    def setup_opts( self, parser ):
        """Add any options to the parser that this command needs."""
        pass
    def execute( self, context, options, args ):
        """Execute the command in some application context with some options and args."""
        raise NotImplemented

你需要为InstallRemove 和其他你需要的命令创建子类。
你的整个应用程序看起来像这样。
commands = [ 
    Install(),
    Remove(),
]
def main():
    parser= optparse.OptionParser()
    for c in commands:
        c.setup_opts( parser )
    options, args = parser.parse()
    command= None
    for c in commands:
        if c.name.startswith(args[0].lower()):
            command= c
            break
    if command:
        status= command.execute( context, options, args[1:] )
    else:
        logger.error( "Command %r is unknown", args[0] )
        status= 2
    sys.exit( status )

0

WSGI库werkzeug提供了管理脚本实用工具,这些工具可能会满足您的需求,或者至少给您提供如何自行进行内省的提示。

from werkzeug import script

# actions go here
def action_test():
    "sample with no args"
    pass

def action_foo(name=2, value="test"):
    "do some foo"
    pass

if __name__ == '__main__':
    script.run()

这将生成以下帮助信息:

$ python /tmp/test.py --help
usage: test.py <action> [<options>]
       test.py --help

actions:
  foo:
    do some foo

    --name                        integer   2
    --value                       string    test

  test:
    sample with no args

动作是在同一模块中以 "action_" 开头的函数,它接受多个参数,其中每个参数都有一个默认值。默认值的类型指定了参数的类型。

然后可以通过位置或使用 shell 中的 --name=value 传递参数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接