代码之家  ›  专栏  ›  技术社区  ›  user2064000

有没有办法通过Python点击自动处理异常?

  •  7
  • user2064000  · 技术社区  · 7 年前

    点击 exception handling documentation Abort , EOFError KeyboardInterrupt

    对于我正在编写的应用程序,可以从很多方面生成异常。终止应用程序是正确的步骤,但打印堆栈跟踪不是。我总是可以手动执行此操作:

    @cli.command()
    def somecommand:
      try:
        # ...
      except Exception as e:
        click.echo(e)
    

    但是,有没有办法让Click自动处理所有异常?

    2 回复  |  直到 7 年前
        1
  •  12
  •   jdno    7 年前

    在我们的CLI中,所有命令都分组在单个命令组下。这允许我们实现每个命令需要执行的一些行为。其中一部分是异常处理。

    我们的切入点如下:

     @click.group()
     @click.pass_context
     def entry_point(ctx):
          ctx.obj = {"example": "This could be the configuration"}
    

    context ,但您也可以定义一个不执行任何操作的空方法。其他命令可以通过使用 @entry_point.command() 装饰工 entry_point.add_command(cmd)

    对于异常处理,我们将 entry_point 在另一种处理异常的方法中:

     def safe_entry_point():
          try:
              entry_point()
          except Exception as e:
              click.echo(e)
    

    在里面 setup.py ,我们为CLI配置入口点并将其指向包装器:

     entry_points={
        'console_scripts': [
            'cli = my.package:safe_entry_point'
        ]
    }
    

    CLI的命令可以通过其命令组执行:例如。 cli command .

    可能还有更优雅的解决方案,但我们就是这样解决的。虽然它引入了命令组作为CLI中的最高级别元素,但它允许我们在单个位置处理所有异常,而不需要在每个命令中重复错误处理。

        2
  •  1
  •   Yash Rathi    3 年前

    如果您只想处理某些CLI命令的异常。您可以使用另一个装饰器来处理异常。

    import click
    from functools import wraps, partial
    
    
    class NumberTooLarge(Exception):
        pass
    
    def catch_exception(func=None, *, handle):
        if not func:
            return partial(catch_exception, handle=handle)
    
        @wraps(func)
        def wrapper(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except handle as e:
                raise click.ClickException(e)
    
        return wrapper
    
    @click.command()
    @click.option("--count", default=1, help="Number of greetings.")
    @catch_exception(handle=(NumberTooLarge, ValueError))
    def hello(count):
        """Simple program that greets NAME for a total of COUNT times."""
        if count > 100:
            raise NumberTooLarge('count cannot be greater than 100')
        if count < 0:
            raise ValueError('count too small')
        click.echo('Great choice!')
    
    
    if __name__ == "__main__":
        hello()