如果它已经存在,为什么我必须导入回溯?
Why do I have to import traceback if it already exists?
如果我在 Python 中写了一些东西并且出了问题,我会自动得到一个回溯。
例如:
#!/usr/bin/env python
print("this will raise a division by zero exception")
print(2/0)
它会自动抛出异常回溯
>>> %Run test.py
this will raise a division by zero exception
Traceback (most recent call last):
File "/home/pi/Desktop/test.py", line 4, in <module>
print(2/0)
ZeroDivisionError: division by zero
>>>
现在,假设我不希望程序崩溃并烧毁,但我想优雅地处理异常 - 比如我需要关闭文件或其他任何东西。
即:
#!/usr/bin/env python
import sys
try:
print("Assume I'm doing something with a resource, like a file")
print(". . . and something goes wrong\n")
print("(This will raise a division by zero exception when I try to \"print(2/0)\")\n")
print(2/0)
except BaseException as e:
print(". . . and I want to handle the exception gracefully:\n")
print("Oops! Something happened! (",e, ")\n")
sys.exit(0)
这符合我的预期:
>>> %Run test.py
Assume I'm doing something with a resource, like a file
. . . and something goes wrong
(This will raise a division by zero exception when I try to "print(2/0)")
. . . and I want to handle the exception gracefully:
Oops! Something happened! ( division by zero )
─────────────────────────────────────────────────────────────────────────────────────────────────
Python 3.7.3 (/usr/bin/python3)
>>>
但是,如果我尝试手动处理异常,我被告知为了获得系统提供的回溯,(错误的调用堆栈和位置),我必须导入回溯。
当我这样做时,我可以获得我想要的所有信息。
#!/usr/bin/env python
import sys
import traceback
try:
print("Assume I'm doing something with a resource, like a file")
print(". . . and something goes wrong\n")
print("(This will raise a division by zero exception when I try to \"print(2/0)\")\n")
print(2/0)
except BaseException as e:
print(". . . and I want to handle the exception gracefully:\n")
print("Oops! Something happened! (",e, ")\n")
traceback.print_exc()
sys.exit(0)
预期结果:
────────────────────────────────────────────────────────────────────────────────────────────────
Python 3.7.3 (/usr/bin/python3)
>>> %Run test.py
Assume I'm doing something with a resource, like a file
. . . and something goes wrong
(This will raise a division by zero exception when I try to "print(2/0)")
. . . and I want to handle the exception gracefully:
Oops! Something happened! ( division by zero )
Traceback (most recent call last):
File "/home/pi/Desktop/test.py", line 9, in <module>
print(2/0)
ZeroDivisionError: division by zero
─────────────────────────────────────────────────────────────────────────────────────────────────
Python 3.7.3 (/usr/bin/python3)
>>>
“回溯”似乎已经存在,因为回溯在未处理的异常上是自动的
如果我使用 try/except 块,为什么我必须导入回溯,但如果不使用则不需要?
回溯反映了 Python 解释器在某些代码执行过程中给定点的状态。 Python 解释器显然可以访问自己的状态,并在抛出异常但未处理时通过打印错误消息与用户共享。它还允许代码访问它——通过 traceback 模块,这就是你需要导入它的原因。
当引发未在 try...except
中捕获的异常时,Python 的默认行为是打印回溯并退出。如果你确实抓住了它,那么默认值就不会发生。你必须决定如何处理它。如果您决定打印回溯,您现在必须通过导入回溯模块并使用那里的方法来明确地执行它。然而,这并不是绝对必要的,因为您可以只检查当前的回溯对象(来自 sys.exc_info()
),然后编写您自己的格式化程序。
"Traceback" appears to already exist as the traceback is automatic on unhandled exceptions
您所看到的是 sys.excepthook
的默认行为,即在程序从未处理的异常退出之前打印回溯到 stderr。
亲身体验:
# example.py
import sys
sys.excepthook = lambda *args: None
print("before")
1/0
print("after")
上面的脚本将退出 non-zero,但不会打印回溯,因为挂钩已替换为 no-op。而“after”不会被打印出来,因为这个过程已经退出了。因此,对于未处理的异常,回溯并不完全是“自动”的,而是默认配置。
通过调用 sys.exit(0)
,您有意抑制 ZeroDivisionError
异常。解释器将以零 return 代码退出,就 except 挂钩而言,您已经“处理”了 ZeroDivisionError
并选择退出回溯打印 (src).
traceback 存在,解释器可以使用它(例如打印它),但只有导入它才能使用它。如果您不使用 try/except 块,您将没有机会导入它。
如果我在 Python 中写了一些东西并且出了问题,我会自动得到一个回溯。
例如:
#!/usr/bin/env python
print("this will raise a division by zero exception")
print(2/0)
它会自动抛出异常回溯
>>> %Run test.py
this will raise a division by zero exception
Traceback (most recent call last):
File "/home/pi/Desktop/test.py", line 4, in <module>
print(2/0)
ZeroDivisionError: division by zero
>>>
现在,假设我不希望程序崩溃并烧毁,但我想优雅地处理异常 - 比如我需要关闭文件或其他任何东西。
即:
#!/usr/bin/env python
import sys
try:
print("Assume I'm doing something with a resource, like a file")
print(". . . and something goes wrong\n")
print("(This will raise a division by zero exception when I try to \"print(2/0)\")\n")
print(2/0)
except BaseException as e:
print(". . . and I want to handle the exception gracefully:\n")
print("Oops! Something happened! (",e, ")\n")
sys.exit(0)
这符合我的预期:
>>> %Run test.py
Assume I'm doing something with a resource, like a file
. . . and something goes wrong
(This will raise a division by zero exception when I try to "print(2/0)")
. . . and I want to handle the exception gracefully:
Oops! Something happened! ( division by zero )
─────────────────────────────────────────────────────────────────────────────────────────────────
Python 3.7.3 (/usr/bin/python3)
>>>
但是,如果我尝试手动处理异常,我被告知为了获得系统提供的回溯,(错误的调用堆栈和位置),我必须导入回溯。
当我这样做时,我可以获得我想要的所有信息。
#!/usr/bin/env python
import sys
import traceback
try:
print("Assume I'm doing something with a resource, like a file")
print(". . . and something goes wrong\n")
print("(This will raise a division by zero exception when I try to \"print(2/0)\")\n")
print(2/0)
except BaseException as e:
print(". . . and I want to handle the exception gracefully:\n")
print("Oops! Something happened! (",e, ")\n")
traceback.print_exc()
sys.exit(0)
预期结果:
────────────────────────────────────────────────────────────────────────────────────────────────
Python 3.7.3 (/usr/bin/python3)
>>> %Run test.py
Assume I'm doing something with a resource, like a file
. . . and something goes wrong
(This will raise a division by zero exception when I try to "print(2/0)")
. . . and I want to handle the exception gracefully:
Oops! Something happened! ( division by zero )
Traceback (most recent call last):
File "/home/pi/Desktop/test.py", line 9, in <module>
print(2/0)
ZeroDivisionError: division by zero
─────────────────────────────────────────────────────────────────────────────────────────────────
Python 3.7.3 (/usr/bin/python3)
>>>
“回溯”似乎已经存在,因为回溯在未处理的异常上是自动的
如果我使用 try/except 块,为什么我必须导入回溯,但如果不使用则不需要?
回溯反映了 Python 解释器在某些代码执行过程中给定点的状态。 Python 解释器显然可以访问自己的状态,并在抛出异常但未处理时通过打印错误消息与用户共享。它还允许代码访问它——通过 traceback 模块,这就是你需要导入它的原因。
当引发未在 try...except
中捕获的异常时,Python 的默认行为是打印回溯并退出。如果你确实抓住了它,那么默认值就不会发生。你必须决定如何处理它。如果您决定打印回溯,您现在必须通过导入回溯模块并使用那里的方法来明确地执行它。然而,这并不是绝对必要的,因为您可以只检查当前的回溯对象(来自 sys.exc_info()
),然后编写您自己的格式化程序。
"Traceback" appears to already exist as the traceback is automatic on unhandled exceptions
您所看到的是 sys.excepthook
的默认行为,即在程序从未处理的异常退出之前打印回溯到 stderr。
亲身体验:
# example.py
import sys
sys.excepthook = lambda *args: None
print("before")
1/0
print("after")
上面的脚本将退出 non-zero,但不会打印回溯,因为挂钩已替换为 no-op。而“after”不会被打印出来,因为这个过程已经退出了。因此,对于未处理的异常,回溯并不完全是“自动”的,而是默认配置。
通过调用 sys.exit(0)
,您有意抑制 ZeroDivisionError
异常。解释器将以零 return 代码退出,就 except 挂钩而言,您已经“处理”了 ZeroDivisionError
并选择退出回溯打印 (src).
traceback 存在,解释器可以使用它(例如打印它),但只有导入它才能使用它。如果您不使用 try/except 块,您将没有机会导入它。