简体   繁体   English

如何在 Python 3 中打印异常?

[英]How to print an exception in Python 3?

Right now, I catch the exception in the except Exception: clause, and do print(exception) .现在,我在except Exception:子句中捕获异常,并执行print(exception) The result provides no information since it always prints <class 'Exception'> .结果不提供任何信息,因为它总是打印<class 'Exception'> I knew this used to work in python 2, but how do I do it in python3?我知道这曾经在 python 2 中工作,但我如何在 python3 中做到这一点?

I'm guessing that you need to assign the Exception to a variable.我猜您需要将Exception分配给一个变量。 As shown in the Python 3 tutorial :Python 3 教程所示

def fails():
    x = 1 / 0

try:
    fails()
except Exception as ex:
    print(ex)

To give a brief explanation, as is a pseudo-assignment keyword used in certain compound statements to assign or alias the preceding statement to a variable.简要说明一下, as是在某些复合语句中使用的伪赋值关键字,用于将前面的语句赋值或别名给变量。

In this case, as assigns the caught exception to a variable allowing for information about the exception to stored and used later, instead of needing to be dealt with immediately.在这种情况下, as将捕获的异常分配给一个变量,允许存储和稍后使用有关异常的信息,而不是需要立即处理。 (This is discussed in detail in the Python 3 Language Reference: The try Statement .) (这在Python 3 语言参考: try语句中有详细讨论。)


The other compound statement using as is the with 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...

Here, with statements are used to wrap the execution of a block with methods defined by context managers .这里, with语句用于用上下文管理器定义的方法包装块的执行。 This functions like an extended try...except...finally statement in a neat generator package, and the as statement assigns the generator-produced result from the context manager to a variable for extended use.这就像一个扩展的try...except...finally语句在一个整洁的生成器包中,并且as语句将生成器生成的结果从上下文管理器分配给一个变量以供扩展使用。 (This is discussed in detail in the Python 3 Language Reference: The with Statement .) (这在Python 3 语言参考中详细讨论with语句。)


Finally, as can be used when importing modules, to alias a module to a different (usually shorter) name:最后, as可导入时模块,别名到一个不同的(通常较短)的名称的模块一起使用:

import foo.bar.baz as fbb

This is discussed in detail in the Python 3 Language Reference: The import Statement .这在Python 3 语言参考: import语句中有详细讨论。

These are the changes since python 2:这些是自 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)

You can look into the standard library module traceback for fancier stuff.您可以查看标准库模块回溯以获得更好的东西。

Try尝试

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

this will print the representation given by e.__str__() :这将打印由e.__str__()给出的表示:

"name 'undefined_var' is not defined" “名称 'undefined_var' 未定义”

you can also use:您还可以使用:

print(repr(e))

which will include the Exception class name:这将包括异常类名:

"NameError("name 'undefined_var' is not defined",)" "NameError("name 'undefined_var' 未定义",)"

Here is the way I like that prints out all of the error stack.这是我喜欢的打印所有错误堆栈的方式。

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())

The output looks as the follows:输出如下所示:

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

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

Although if you want a code that is compatible with both python2 and python3 you can use this:虽然如果你想要一个与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)

[In Python3] [在 Python3 中]

Let's say you want to handle an IndexError and print the traceback, you can do the following:假设您要处理IndexError并打印回溯,您可以执行以下操作:

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

Note: You can use the format_tb function instead of print_tb to get the traceback as a string for logging purposes.注意:您可以使用format_tb函数而不是print_tb将回溯作为用于日志记录的字符串获取。 Hope this helps.希望这可以帮助。

I've use this :我用过这个:

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

Let me know if it does not work for you !!如果它不适合您,请告诉我!!

Don't use print(e), since that won't print a stack trace, which is a nightmare for debugging.不要使用print(e),因为它不会打印堆栈跟踪,这是调试的噩梦。 traceback.print_exception is what you're looking for: traceback.print_exception 是你要找的:

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

You can do:你可以做:

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

Reference 参考

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM