【问题标题】:How to print an exception in Python 3?如何在 Python 3 中打印异常?
【发布时间】:2017-05-26 14:15:39
【问题描述】:

现在,我在except Exception: 子句中捕获了异常,然后执行print(exception)。结果没有提供任何信息,因为它总是打印<class 'Exception'>。我知道这曾经在 python 2 中工作,但我如何在 python3 中做到这一点?

【问题讨论】:

  • 这没有意义,到底exception这个名字绑定了什么?请发布出现此行为的 sn-p,最重要的是初始化名称 exception 的部分。

标签: python python-3.x exception web-scraping


【解决方案1】:

你可以这样做:

with self.assertRaisesMessage(ValueError, 'invalid literal for int()'):
  int('a')

Reference

【讨论】:

    【解决方案2】:

    我猜你需要将Exception 分配给一个变量。作为shown in the Python 3 tutorial

    def fails():
        x = 1 / 0
    
    try:
        fails()
    except Exception as ex:
        print(ex)
    

    为了简要说明,as 是在某些复合语句中用于将前面的语句分配或别名给变量的伪赋值关键字。

    在这种情况下,as 将捕获的异常分配给一个变量,允许存储和稍后使用有关异常的信息,而不是需要立即处理。

    (这在Python 3 Language Reference: The try Statement中有详细讨论。)


    还有其他复合语句使用as。第一个是with 声明:

    @contextmanager
    def opening(filename):
        f = open(filename)
        try:
            yield f
        finally:
            f.close()
    
    with opening(filename) as f:
        # ...read data from f...
    

    这里,with 语句用于用context managers 定义的方法包装块的执行。这就像一个整洁的生成器包中的扩展 try...except...finally 语句,as 语句将生成器生成的结果从上下文管理器分配给一个变量以供扩展使用。

    (这在Python 3 Language Reference: The with Statement中有详细讨论。)


    从 Python 3.10 开始,match 语句也使用 as

    from random import randint
    
    match randint(0, 2):
        case 0|1 as low:
            print(f"{low} is a low number")
        case _:
            print("not a low number")
    

    match 语句采用一个表达式(在本例中为randint(0, 2))并将其值与每个case 分支一次一个进行比较,直到其中一个成功,此时它执行该分支的块。在case 分支中,如果分支成功,as 可用于将分支的值分配给变量。如果不成功,则不绑定。

    match 声明由tutorial 覆盖,并在Python 3 Language Reference: match Statements 中详细讨论。)


    最后,as 可以在导入模块时使用,将模块别名为不同(通常更短)的名称:

    import foo.bar.baz as fbb
    

    这在Python 3 Language Reference: The import Statement中有详细讨论。

    【讨论】:

      【解决方案3】:

      不要使用 print(e),因为它不会打印堆栈跟踪,这是调试的噩梦。 traceback.print_exception 是您要查找的内容:

      import traceback
      try:
          assert False
      except Exception as e:
          traceback.print_exception(e)
      

      【讨论】:

        【解决方案4】:

        试试

        try:
            print(undefined_var)
        except Exception as e:
            print(e)
        

        这将打印e.__str__()给出的表示:

        “名称'undefined_var'未定义”

        你也可以使用:

        print(repr(e))
        

        其中将包括异常类名称:

        "NameError("name 'undefined_var' 未定义",)"

        【讨论】:

          【解决方案5】:

          [在 Python3 中]

          假设您要处理IndexError 并打印回溯,您可以执行以下操作:

          from traceback import print_tb 
          empty_list = [] 
          try: 
              x = empty_list[100]
          except IndexError as index_error: 
              print_tb(index_error.__traceback__)
          

          注意:您可以使用format_tb 函数而不是print_tb 来获取作为用于记录目的的字符串的回溯。 希望这可以帮助。

          【讨论】:

            【解决方案6】:

            如果你想要一个同时兼容 python2python3 的代码,你可以使用这个:

            import logging
            try:
                1/0
            except Exception as e:
                if hasattr(e, 'message'):
                    logging.warning('python2')
                    logging.error(e.message)
                else:
                    logging.warning('python3')
                    logging.error(e)
            

            【讨论】:

              【解决方案7】:

              这是我喜欢的打印所有错误堆栈的方式。

              import logging
              
              try:
                  1 / 0
              except Exception as _e:
                  # any one of the follows:
                  # print(logging.traceback.format_exc())
                  logging.error(logging.traceback.format_exc())
              

              输出如下:

              ERROR:root:Traceback (most recent call last):
                File "/PATH-TO-YOUR/filename.py", line 4, in <module>
                  1 / 0
              ZeroDivisionError: division by zero
              

              LOGGING_FORMAT

              LOGGING_FORMAT = '%(asctime)s\n  File "%(pathname)s", line %(lineno)d\n  %(levelname)s [%(message)s]'
              

              【讨论】:

                【解决方案8】:

                我用过这个:

                except (socket.timeout, KeyboardInterrupt) as e:
                    logging.debug("Exception : {}".format(str(e.__str__).split(" ")[3]))
                    break
                

                如果它不适合你,请告诉我!!

                【讨论】:

                  【解决方案9】:

                  这些是自 python 2 以来的变化:

                      try:
                          1 / 0
                      except Exception as e: # (as opposed to except Exception, e:)
                                             # ^ that will just look for two classes, Exception and e
                          # for the repr
                          print(repr(e))
                          # for just the message, or str(e), since print calls str under the hood
                          print(e)
                          # the arguments that the exception has been called with. 
                          # the first one is usually the message. (OSError is different, though)
                          print(e.args)
                  

                  您可以查看标准库模块 traceback 以获得更高级的内容。

                  【讨论】:

                  • Python 3 似乎没有message 属性,并且str(e) 将错误的位置和类型添加到消息中;对吗?
                  • 可能晚了,但只是为了清除...... str(e) 似乎只返回 python 3 中的消息,即:'name 're' is not defined'
                  猜你喜欢
                  • 2010-12-01
                  • 2017-12-21
                  • 2020-10-18
                  • 2013-02-24
                  • 2016-01-19
                  • 1970-01-01
                  • 2021-01-17
                  • 1970-01-01
                  相关资源
                  最近更新 更多