如何调试 Python 单击命令行界面应用程序



我使用 python 中的点击库构建了一个 cli 应用程序。没有关于如何调试命令的文档。

无需单击,只需在 IDE 中调试 python 文件就很容易,但是当我们使用 click 时,命令需要在 setup.py 中通过console_scripts设置运行。

这没有很好的文档记录,但您可以直接调用命令函数,因此可以在调试器中运行代码:

示例代码:

import click
@click.command()
@click.option('--my_arg', default=1, help='a number')
def my_command(my_arg):
    click.echo("my_arg='%d'" % my_arg)
if __name__ == '__main__':
    my_command(['--my_arg', '3'])

结果:

my_arg='3'

我参加聚会迟到了几年,但以防其他人像我刚才那样来这里寻找答案:

使用 CliRunner.invoke(( 调用函数将返回一个带有 "exc_info" 属性的 "Result" 对象。 你可以像这样将其提供给 traceback.print_exception((:

runner = CliRunner()
result = runner.invoke(my_command)
traceback.print_exception(*result.exc_info)

setup.py 生成:

  • console_script.exe
  • console_script-script.py

来自CMDLINE:

console_app --help

扩展到 IDE 配置 cmd:

python <absolute path to>console_app-script.py --help

在 PyCharm 2018.2 中测试 - 您可以设置和命中断点并保留预期的 cmdline/arg 范例。

我发现编写测试是调试的好方法 单击CLI 应用程序:http://click.pocoo.org/5/testing/

从你的函数和测试开始非常简单,然后添加到它,确保测试告诉你你需要它做什么......

此外,设置默认值有助于:

def run_files(input_file='/path/to/input_file', output_file='/路径/到/output_file'(: click.echo(input_file, output_file(

我通常还会设置日志记录并在开始时记录所有内容:

logging.basicConfig(format='%(levelname)s %(message)s', level=logging.DEBUG)

然后在整个过程中撒上这些(IU 有带有时间戳内容的实用程序,但这不是必需的(:

logging.info('[{0}] Blah blah selected...'.format(
             utils.get_timestamp()))

您也可以使用printclick.echo来执行此操作。

你可以像这样使用 pdb,放在你想要调试的代码中:

import pdb
pdb.set_trace()

例如:

import click
@click.command()
def hello():
    msg = "hi"
    num = 3
    import pdb
    pdb.set_trace()
    click.echo('Hello1!')
    click.echo('Hello2!')
    click.echo(msg + num)
if __name__ == '__main__':
    hello()

然后你可以使用 pdb:

$ python hello.py 
> /home/eduardo/w/ifpb/cozer/hello.py(11)hello()
-> click.echo('Hello1!')
(Pdb) msg
'hi'
(Pdb) num
3
(Pdb) msg = hello
(Pdb) b 13
Breakpoint 1 at /home/eduardo/w/ifpb/cozer/hello.py:13
(Pdb) c
Hello1!
Hello2!
> /home/eduardo/w/ifpb/cozer/hello.py(13)hello()
-> click.echo(msg + num)
(Pdb) c
Traceback (most recent call last):
  File "hello.py", line 16, in <module>
    hello()
  File "/home/eduardo/w/ifpb/cozer/venv/lib/python3.5/site-packages/click/core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "/home/eduardo/w/ifpb/cozer/venv/lib/python3.5/site-packages/click/core.py", line 717, in main
    rv = self.invoke(ctx)
  File "/home/eduardo/w/ifpb/cozer/venv/lib/python3.5/site-packages/click/core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/eduardo/w/ifpb/cozer/venv/lib/python3.5/site-packages/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "hello.py", line 13, in hello
    click.echo(msg + num)
TypeError: unsupported operand type(s) for +: 'Command' and 'int'

错误后,我们可以再次尝试解决方案:

$ python hello.py 
> /home/eduardo/w/ifpb/cozer/hello.py(11)hello()
-> click.echo('Hello1!')
(Pdb) msg
'hi'
(Pdb) num
3
(Pdb) b 13
Breakpoint 1 at /home/eduardo/w/ifpb/cozer/hello.py:13
(Pdb) c
Hello1!
Hello2!
> /home/eduardo/w/ifpb/cozer/hello.py(13)hello()
-> click.echo(msg + num)
(Pdb) num = str(num)
(Pdb) c
hi3

如果您希望调试在单击命令函数之后执行的模块/类。

一种经济实惠的解决方案是创建一个脚本来模拟执行命令后执行的流。

然后,通过将调试点放在所需的行中,可以实现调试功能。

这是我在简短的网络搜索后想到要做的。

最新更新