python click framework-oop方法中的自定义多命令实现

时间:2019-10-10 12:08:02

标签: python python-3.x python-click

我写了一些脚本,试图与click集成。所有的脚本都是用python OOP编写的。

问题是我试图以oop的方式构建命令部分,但无法正确执行。

让我告诉你,我要做什么,请注意,我在这里共享的虚拟代码与真实代码非常相似。

第一件事是目录结构:

-customcmd <dir>
|
|->commands <dir>
|  -> abc-command.py
|  -> __init__.py
|
|->__init__.py
|->main.py
|->setup.py

1)我创建了一个名为main.py的文件,其中包含以下代码:

import click
import os

plugin_folder = os.path.join(os.path.dirname(__file__), 'commands')

class MyCLI(click.MultiCommand):

    def list_commands(self, ctx):
        rv = []
        for filename in os.listdir(plugin_folder):
            if filename.startswith('__'):
                continue
            if filename.endswith('.py'):
                rv.append(filename[:-3])
        rv.sort()
        return rv

    def get_command(self, ctx, name):
        ns = {}
        fn = os.path.join(plugin_folder, name + '.py')
        with open(fn) as f:
            code = compile(f.read(), fn, 'exec')
            eval(code, ns, ns)
        return ns['cli']

cli = MyCLI()#help='This tool\'s subcommands are loaded from a ''plugin folder dynamically.'
if __name__ == '__main__':
    cli()

2)abc-command.py

@click.command()
@click.option("--file-loc", '-fl', type=open, required=True, default=None, help="Path to the file")

def cli(file_loc):
    """ 
        This is test command

    """
    print("Path to file {}".format(file_loc))

  • 调用main.py时,上述代码的输出:
(automation) K:\Pythonenv\automation\customcmd>python main.py
Usage: main.py [OPTIONS] COMMAND [ARGS]...

Options:
  --help  Show this message and exit.

Commands:
  policyresult  This is test command
  • 调用子命令时上述代码的输出:
(automation) K:\Pythonenv\automation\customcmd>python main.py policyresult --help
Usage: main.py policyresult [OPTIONS]

  This is test command

Options:
  -fl, --file-loc OPEN    Path to the file  [required]
  --help                  Show this message and exit.

3)这就是我转换abc-command.py代码的过程代码的方式:

  class policyresult():



    def __init__(self):
        pass


    @click.command()
    @click.option("--file-loc", '-fl', type=open, required=True, default=None, help="Path to the file")

    def cli(self,file_loc):
        """ 
            This is test command

        """
        print("Path to file {}".format(file_loc))



obj = policyresult()
obj.cli()

  • 在abc-command.py中按程序进行操作时,上述代码的输出与先前的输出不匹配:

我在这里打电话给main.py

(automation) K:\Pythonenv\automation\customcmd>python main.py
Usage: main.py [OPTIONS]
Try "main.py --help" for help.

Error: Missing option "--file-loc" / "-fl".

在上面的输出中,您可以看到它直接进入了子命令选项中,并且也给出了错误。

据我所知main.py中的list_commands()无法列出命令,这一部分我不明白为什么它不能正常工作。

我尝试了各种方法,但是由于我的输出不匹配,所以无法在abc-command.py中找到实现OOP的正确方法。

我是此点击框架的新手,请根据需要对我的方法提出任何新的建议。

请对此进行调查,对于这种奇怪的解释方式,我们感到抱歉。

1 个答案:

答案 0 :(得分:-1)

abc-command.py是在单击分析命令选项之前进行评估的,因为文件中的这一行调用了cli方法:

obj.cli()

此外,在为多命令实现的get_command方法中,命令应该在其命名空间中公开“ cli”名称。

要解决此错误,请在abc-command.py中使用以下命令更新调用cli命令的行:

cli = obj.cli

以便在abc-command.py模块中公开cli名称