6.11.traceback
Windows 10
Python 3.7.3 @ MSC v.1915 64 bit (AMD64)
Latest build date 2020.08.11
from toolkit import H
import re
import numpy as np
import traceback
import sys
FrameSummary 类
FrameSummary对象:表示trace back中的单个frame。它可以选择包含一个框架局部变量的字符串化版本。
traceback.FrameSummary(filename, lineno, name, lookup_line=True,
locals=None, line=None)
-
如果 lookup_line 是 False ,直到 FrameSummary 有 line 访问的属性(在将其强制转换为元组时也会发生这种情况)。
-
line 可以直接提供,并且可以完全阻止行查找的发生。
-
locals 是可选的局部变量字典,如果提供,变量表示形式将存储在摘要中以供以后显示。
# 获取当前frame
frame = sys._getframe()
# 利用当前frame的信息创建一个FrameSummary对象
traceback.FrameSummary(filename=frame.f_code.co_filename,
lineno=frame.f_lineno,
name=frame.f_code.co_name,
lookup_line=True,
locals=frame.f_locals,
line=None)
<FrameSummary file <ipython-input-1-8a9a38cc1974>, line 2 in <module>>
StackSummary 类
StackSummary对象:表示准备格式化的调用堆栈。StackSummary对象是包含多个FrameSummary对象的可迭代容器。
构造方法
traceback.StackSummary.extract(frame_gen, limit=None,
lookup_lines=True,
capture_locals=False)
-
frame生成器:e.g.
walk_stack()
或walk_tb()
-
limit:只从 frame_gen 提取 limit 个 frame 对象
-
lookup_lines:如果是False ,则返回的FrameSummary对象尚未读取其行,因此创建 StackSummary 的代价比较低(如果不是真正格式化的话可能很有价值)。
-
capture_locals:如果是True 则每个FrameSummary的局部变量会被捕获,用一个对象表示。
traceback.StackSummary.from_list(a_list)
从提供的旧样式的元组列表构造一个StackSummary对象。每个元组应该是filename,lineno,name,line为元素的4元组。
其他方法
traceback.StackSummary.format(self)
返回准备打印的字符串列表。
列表中的每一个元素(字符串)对应于堆栈中的一个frame。每个字符串以换行符结尾,对于具有源文本行的项目,字符串也可以包含内部换行符。对于同一帧和同一行的长序列,显示前几次重复,然后显示摘要行,说明进一步重复的确切数量。
获取 frame 堆栈
traceback.walk_stack(f)
从给frame中跟踪f.f_back
后的堆栈,得到每个帧的帧和行号。如果f
为None,则使用当前堆栈。它与StackSummary.extract()
一起使用。
traceback.walk_tb(tb)
在tb_next
之后执行回溯,得到每个帧的帧和行号。它与StackSummary.extract()
一起使用。
示例
def call_function(f, recursion_level=2):
if recursion_level:
return call_function(f, recursion_level - 1)
else:
return f()
def f():
summary = traceback.StackSummary.extract(
traceback.walk_stack(None)
)
return ''.join(summary.format())
def format_traceback_str(string):
need_replaced = re.findall(r'"(.*)"', string)
need_replaced_unique = []
for i in need_replaced:
if i not in need_replaced_unique:
need_replaced_unique.append(i)
num = 1
for file_str in need_replaced_unique:
if num > 3:
output_end_index = string.index(f'"{num - 1}.py"')
string = string[0:output_end_index]
break
if not file_str.startswith("<ipython-input"):
string = string.replace(file_str, f"{num}.py")
num += 1
return string
print('Calling f() directly:')
string = f()
print(format_traceback_str(string))
print()
print('Calling f() from 3 levels deep:')
string = call_function(f)
print(format_traceback_str(string))
Calling f() directly:
File "<ipython-input-1-8548a9dafead>", line 9, in f
traceback.walk_stack(None)
File "<ipython-input-1-8548a9dafead>", line 34, in <module>
string = f()
File "1.py", line 3331, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "1.py", line 3254, in run_ast_nodes
if (await self.run_code(code, result, async_=asy)):
File "1.py", line 3063, in run_cell_async
interactivity=interactivity, compiler=compiler, result=result)
File "2.py", line 68, in _pseudo_sync_runner
coro.send(None)
File "1.py", line 2886, in _run_cell
return runner(coro)
File "1.py", line 2858, in run_cell
raw_cell, store_history, silent, shell_futures)
File
Calling f() from 3 levels deep:
File "<ipython-input-1-8548a9dafead>", line 9, in f
traceback.walk_stack(None)
File "<ipython-input-1-8548a9dafead>", line 5, in call_function
return f()
File "<ipython-input-1-8548a9dafead>", line 3, in call_function
return call_function(f, recursion_level - 1)
File "<ipython-input-1-8548a9dafead>", line 3, in call_function
return call_function(f, recursion_level - 1)
File "<ipython-input-1-8548a9dafead>", line 39, in <module>
string = call_function(f)
File "1.py", line 3331, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "1.py", line 3254, in run_ast_nodes
if (await self.run_code(code, result, async_=asy)):
File "1.py", line 3063, in run_cell_async
interactivity=interactivity, compiler=compiler, result=result)
File "2.py", line 68, in _pseudo_sync_runner
coro.send(None)
File "1.py", line 2886, in _run_cell
return runner(coro)
File "1.py", line 2858, in run_cell
raw_cell, store_history, silent, shell_futures)
File
为了显示更简洁的结果,trackback信息中的Python文件名用数字代替,并且省略一些末尾的trackback信息,这个过程由format_traceback_str
函数完成。省略的信息在f()
和call_function(f)
返回的结果中都是相同的。
实际上,我们完全可以自定义trackback字符串的格式:
import traceback
import sys
template = (
'"{fs.filename:<26}":{fs.lineno}:{fs.name}:\n'
' {fs.line}'
)
def f():
summary = traceback.StackSummary.extract(
traceback.walk_stack(None)
)
string = ""
for fs in summary:
string += template.format(fs=fs) + "\n"
return string
print('Calling f() directly:')
string = f()
print(format_traceback_str(string))
print()
print('Calling f() from 3 levels deep:')
string = call_function(f)
print(format_traceback_str(string))
Calling f() directly:
"<ipython-input-1-4b8f40d1d7c9>":11:f:
traceback.walk_stack(None)
"<ipython-input-1-4b8f40d1d7c9>":20:<module>:
string = f()
"1.py":3331:run_code:
exec(code_obj, self.user_global_ns, self.user_ns)
"1.py":3254:run_ast_nodes:
if (await self.run_code(code, result, async_=asy)):
"1.py":3063:run_cell_async:
interactivity=interactivity, compiler=compiler, result=result)
"2.py":68:_pseudo_sync_runner:
coro.send(None)
"1.py":2886:_run_cell:
return runner(coro)
"1.py":2858:run_cell:
raw_cell, store_history, silent, shell_futures)
Calling f() from 3 levels deep:
"<ipython-input-1-4b8f40d1d7c9>":11:f:
traceback.walk_stack(None)
"<ipython-input-1-8548a9dafead>":5:call_function:
return f()
"<ipython-input-1-8548a9dafead>":3:call_function:
return call_function(f, recursion_level - 1)
"<ipython-input-1-8548a9dafead>":3:call_function:
return call_function(f, recursion_level - 1)
"<ipython-input-1-4b8f40d1d7c9>":25:<module>:
string = call_function(f)
"1.py":3331:run_code:
exec(code_obj, self.user_global_ns, self.user_ns)
"1.py":3254:run_ast_nodes:
if (await self.run_code(code, result, async_=asy)):
"1.py":3063:run_cell_async:
interactivity=interactivity, compiler=compiler, result=result)
"2.py":68:_pseudo_sync_runner:
coro.send(None)
"1.py":2886:_run_cell:
return runner(coro)
"1.py":2858:run_cell:
raw_cell, store_history, silent, shell_futures)
TracebackException
import traceback
import sys
def produce_exception(recursion_level=2):
sys.stdout.flush()
if recursion_level:
produce_exception(recursion_level - 1)
else:
raise RuntimeError()
print('with no exception:')
exc_type, exc_value, exc_tb = sys.exc_info()
tbe = traceback.TracebackException(exc_type, exc_value, exc_tb)
print(''.join(tbe.format()))
print('\nwith exception:')
try:
produce_exception()
except Exception as err:
exc_type, exc_value, exc_tb = sys.exc_info()
tbe = traceback.TracebackException(
exc_type, exc_value, exc_tb,
)
print(''.join(tbe.format()))
print('\nexception only:')
print(''.join(tbe.format_exception_only()))
with no exception:
None: None
with exception:
Traceback (most recent call last):
File "<ipython-input-1-9d9c5e9aab70>", line 18, in <module>
produce_exception()
File "<ipython-input-1-9d9c5e9aab70>", line 7, in produce_exception
produce_exception(recursion_level - 1)
File "<ipython-input-1-9d9c5e9aab70>", line 7, in produce_exception
produce_exception(recursion_level - 1)
File "<ipython-input-1-9d9c5e9aab70>", line 9, in produce_exception
raise RuntimeError()
RuntimeError
exception only:
RuntimeError
底层异常 API
另一个处理异常报告的方法是使用print_exc()
。它使用sys.exc_info()
来为当前线程存储异常信息,格式化结果,打印文本到文件句柄(默认是 sys.stderr
)。
traceback.print_exc(limit=None, file=None, chain=True)
print_exc()
不需要传入参数,所以在一些场合print_exc()
可能无法获得预期的结果。例如在Python 2.x中执行下述代码:
import traceback
try:
raise TypeError("Oups!")
except Exception:
try:
raise TypeError("Again !?!")
except:
pass
traceback.print_exc()
Traceback (most recent call last):
File "<ipython-input-1-057ba94a4e04>", line 4, in <module>
raise TypeError("Oups!")
TypeError: Oups!
我们可能期待print_exc()
打印出raise TypeError("Again !?!")
语句抛出的异常,但实际上,print_exc()
只打印了raise TypeError("Oups!")
语句抛出的异常。
print_exc()
只是print_exception()
的快捷方式,只不过我们使用后者时需要准确的参数 。print_exception()
的参数通过sys.exc_info()
获取到。
如果您确实需要访问原始的追溯,一种解决方案是将异常信息从exc_info
本地变量中返回,并使用来显示它print_exception
:
import traceback
import sys
try:
raise TypeError("Oups!")
except Exception:
try:
exc_info = sys.exc_info()
print(exc_info)
# do you usefull stuff here
# (potentially raising an exception)
try:
raise TypeError("Again !?!")
except:
pass
# end of useful stuff
finally:
# Display the *original* exception
traceback.print_exception(*exc_info)
del exc_info
# https://stackoverflow.com/questions/3702675/how-to-print-the-full-traceback-without-halting-the-program
# a = []
# for i in traceback.walk_stack(None):
# a.append(i)
# dir(a[0][0])
# frame.f_back
# a[0][0].f_code
(<class 'TypeError'>, TypeError('Oups!'), <traceback object at
0x000001309FD2E308>)
Traceback (most recent call last):
File "<ipython-input-1-c2358bda325a>", line 6, in <module>
raise TypeError("Oups!")
TypeError: Oups!
print_exception()
使用的是format_exception()
来准备要打印的文本。format_exception()
要使用的三个参数与print_exception()
一样,都是exception type, exception value, traceback。
import traceback
import sys
from pprint import pprint
try:
produce_exception()
except Exception as err:
print('format_exception():')
exc_type, exc_value, exc_tb = sys.exc_info()
pprint(
traceback.format_exception(exc_type, exc_value, exc_tb),
width=65,
)
format_exception():
['Traceback (most recent call last):\n',
' File "<ipython-input-1-564aebc46497>", line 6, in <module>\n'
' produce_exception()\n',
' File "<ipython-input-1-9d9c5e9aab70>", line 7, in '
'produce_exception\n'
' produce_exception(recursion_level - 1)\n',
' File "<ipython-input-1-9d9c5e9aab70>", line 7, in '
'produce_exception\n'
' produce_exception(recursion_level - 1)\n',
' File "<ipython-input-1-9d9c5e9aab70>", line 9, in '
'produce_exception\n'
' raise RuntimeError()\n',
'RuntimeError\n']
要想把 traceback 用其他方式处理,比如弄成不同的输出格式,我们可以用 extract_tb()
获取出数据。
import traceback
import sys
import os
template = '{filename:<23}:{linenum}:{funcname}:\n {source}'
try:
produce_exception()
except Exception as err:
print('format_exception():')
exc_type, exc_value, exc_tb = sys.exc_info()
for tb_info in traceback.extract_tb(exc_tb):
filename, linenum, funcname, source = tb_info
if funcname != '<module>':
funcname = funcname + '()'
print(template.format(
filename=os.path.basename(filename),
linenum=linenum,
source=source,
funcname=funcname)
)
format_exception():
<ipython-input-1-5f837b49071f>:8:<module>:
produce_exception()
<ipython-input-1-9d9c5e9aab70>:7:produce_exception():
produce_exception(recursion_level - 1)
<ipython-input-1-9d9c5e9aab70>:7:produce_exception():
produce_exception(recursion_level - 1)
<ipython-input-1-9d9c5e9aab70>:9:produce_exception():
raise RuntimeError()
底层栈 API
有几个与 traceback 相同的函数来对当前调用栈做相同的操作。print_stack()
会打印出当前栈但不引发异常。输出很像 traceback 但并无错误信息。
import traceback
import sys
def f():
traceback.print_stack(file=sys.stdout)
print('Calling f() directly:')
f()
print()
print('Calling f() from 3 levels deep:')
call_function(f)
Calling f() directly:
File "setup_m.py", line 45, in <module>
save_dir=save_dir)
File "G:\Installed\Anaconda3\lib\site-packages\pweave\__init__.py",
line 62, in weave
doc.weave()
File "G:\Installed\Anaconda3\lib\site-packages\pweave\pweb.py", line
192, in weave
self.run()
File "G:\Installed\Anaconda3\lib\site-packages\pweave\pweb.py", line
129, in run
proc.run()
File "G:\Installed\Anaconda3\lib\site-
packages\pweave\processors\base.py", line 46, in run
res = self._runcode(chunk)
File "G:\Installed\Anaconda3\lib\site-
packages\pweave\processors\base.py", line 171, in _runcode
chunk['result'] = self.loadstring(chunk['content'], chunk=chunk)
File "G:\Installed\Anaconda3\lib\site-
packages\pweave\processors\jupyter.py", line 134, in loadstring
return self.run_cell(code_str)
File "G:\Installed\Anaconda3\lib\site-
packages\pweave\processors\jupyter.py", line 58, in run_cell
msg_id = self.kc.execute(src.lstrip(), store_history=False)
File "G:\Installed\Anaconda3\lib\site-
packages\ipykernel\inprocess\client.py", line 102, in execute
self._dispatch_to_kernel(msg)
File "G:\Installed\Anaconda3\lib\site-
packages\ipykernel\inprocess\client.py", line 170, in
_dispatch_to_kernel
kernel.dispatch_shell(stream, msg_parts)
File "G:\Installed\Anaconda3\lib\site-packages\tornado\gen.py", line
209, in wrapper
yielded = next(result)
File "G:\Installed\Anaconda3\lib\site-
packages\ipykernel\kernelbase.py", line 268, in dispatch_shell
yield gen.maybe_future(handler(stream, idents, msg))
File "G:\Installed\Anaconda3\lib\site-
packages\ipykernel\inprocess\ipkernel.py", line 80, in execute_request
super(InProcessKernel, self).execute_request(stream, ident,
parent)
File "G:\Installed\Anaconda3\lib\site-packages\tornado\gen.py", line
209, in wrapper
yielded = next(result)
File "G:\Installed\Anaconda3\lib\site-
packages\ipykernel\kernelbase.py", line 541, in execute_request
user_expressions, allow_stdin,
File "G:\Installed\Anaconda3\lib\site-packages\tornado\gen.py", line
209, in wrapper
yielded = next(result)
File "G:\Installed\Anaconda3\lib\site-
packages\ipykernel\ipkernel.py", line 300, in do_execute
res = shell.run_cell(code, store_history=store_history,
silent=silent)
File "G:\Installed\Anaconda3\lib\site-
packages\ipykernel\zmqshell.py", line 536, in run_cell
return super(ZMQInteractiveShell, self).run_cell(*args, **kwargs)
File "G:\Installed\Anaconda3\lib\site-
packages\IPython\core\interactiveshell.py", line 2858, in run_cell
raw_cell, store_history, silent, shell_futures)
File "G:\Installed\Anaconda3\lib\site-
packages\IPython\core\interactiveshell.py", line 2886, in _run_cell
return runner(coro)
File "G:\Installed\Anaconda3\lib\site-
packages\IPython\core\async_helpers.py", line 68, in
_pseudo_sync_runner
coro.send(None)
File "G:\Installed\Anaconda3\lib\site-
packages\IPython\core\interactiveshell.py", line 3063, in
run_cell_async
interactivity=interactivity, compiler=compiler, result=result)
File "G:\Installed\Anaconda3\lib\site-
packages\IPython\core\interactiveshell.py", line 3254, in
run_ast_nodes
if (await self.run_code(code, result, async_=asy)):
File "G:\Installed\Anaconda3\lib\site-
packages\IPython\core\interactiveshell.py", line 3331, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-1-fb615fd1c94c>", line 8, in <module>
f()
File "<ipython-input-1-fb615fd1c94c>", line 5, in f
traceback.print_stack(file=sys.stdout)
Calling f() from 3 levels deep:
File "setup_m.py", line 45, in <module>
save_dir=save_dir)
File "G:\Installed\Anaconda3\lib\site-packages\pweave\__init__.py",
line 62, in weave
doc.weave()
File "G:\Installed\Anaconda3\lib\site-packages\pweave\pweb.py", line
192, in weave
self.run()
File "G:\Installed\Anaconda3\lib\site-packages\pweave\pweb.py", line
129, in run
proc.run()
File "G:\Installed\Anaconda3\lib\site-
packages\pweave\processors\base.py", line 46, in run
res = self._runcode(chunk)
File "G:\Installed\Anaconda3\lib\site-
packages\pweave\processors\base.py", line 171, in _runcode
chunk['result'] = self.loadstring(chunk['content'], chunk=chunk)
File "G:\Installed\Anaconda3\lib\site-
packages\pweave\processors\jupyter.py", line 134, in loadstring
return self.run_cell(code_str)
File "G:\Installed\Anaconda3\lib\site-
packages\pweave\processors\jupyter.py", line 58, in run_cell
msg_id = self.kc.execute(src.lstrip(), store_history=False)
File "G:\Installed\Anaconda3\lib\site-
packages\ipykernel\inprocess\client.py", line 102, in execute
self._dispatch_to_kernel(msg)
File "G:\Installed\Anaconda3\lib\site-
packages\ipykernel\inprocess\client.py", line 170, in
_dispatch_to_kernel
kernel.dispatch_shell(stream, msg_parts)
File "G:\Installed\Anaconda3\lib\site-packages\tornado\gen.py", line
209, in wrapper
yielded = next(result)
File "G:\Installed\Anaconda3\lib\site-
packages\ipykernel\kernelbase.py", line 268, in dispatch_shell
yield gen.maybe_future(handler(stream, idents, msg))
File "G:\Installed\Anaconda3\lib\site-
packages\ipykernel\inprocess\ipkernel.py", line 80, in execute_request
super(InProcessKernel, self).execute_request(stream, ident,
parent)
File "G:\Installed\Anaconda3\lib\site-packages\tornado\gen.py", line
209, in wrapper
yielded = next(result)
File "G:\Installed\Anaconda3\lib\site-
packages\ipykernel\kernelbase.py", line 541, in execute_request
user_expressions, allow_stdin,
File "G:\Installed\Anaconda3\lib\site-packages\tornado\gen.py", line
209, in wrapper
yielded = next(result)
File "G:\Installed\Anaconda3\lib\site-
packages\ipykernel\ipkernel.py", line 300, in do_execute
res = shell.run_cell(code, store_history=store_history,
silent=silent)
File "G:\Installed\Anaconda3\lib\site-
packages\ipykernel\zmqshell.py", line 536, in run_cell
return super(ZMQInteractiveShell, self).run_cell(*args, **kwargs)
File "G:\Installed\Anaconda3\lib\site-
packages\IPython\core\interactiveshell.py", line 2858, in run_cell
raw_cell, store_history, silent, shell_futures)
File "G:\Installed\Anaconda3\lib\site-
packages\IPython\core\interactiveshell.py", line 2886, in _run_cell
return runner(coro)
File "G:\Installed\Anaconda3\lib\site-
packages\IPython\core\async_helpers.py", line 68, in
_pseudo_sync_runner
coro.send(None)
File "G:\Installed\Anaconda3\lib\site-
packages\IPython\core\interactiveshell.py", line 3063, in
run_cell_async
interactivity=interactivity, compiler=compiler, result=result)
File "G:\Installed\Anaconda3\lib\site-
packages\IPython\core\interactiveshell.py", line 3254, in
run_ast_nodes
if (await self.run_code(code, result, async_=asy)):
File "G:\Installed\Anaconda3\lib\site-
packages\IPython\core\interactiveshell.py", line 3331, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-1-fb615fd1c94c>", line 12, in <module>
call_function(f)
File "<ipython-input-1-8548a9dafead>", line 3, in call_function
return call_function(f, recursion_level - 1)
File "<ipython-input-1-8548a9dafead>", line 3, in call_function
return call_function(f, recursion_level - 1)
File "<ipython-input-1-8548a9dafead>", line 5, in call_function
return f()
File "<ipython-input-1-fb615fd1c94c>", line 5, in f
traceback.print_stack(file=sys.stdout)
format_stack()
准备栈追踪的方式与 format_exception()
一样。
import traceback
import sys
from pprint import pprint
def f():
return traceback.format_stack()
formatted_stack = call_function(f)
pprint(formatted_stack)
[' File "setup_m.py", line 45, in <module>\n
save_dir=save_dir)\n',
' File "G:\\Installed\\Anaconda3\\lib\\site-
packages\\pweave\\__init__.py", '
'line 62, in weave\n'
' doc.weave()\n',
' File "G:\\Installed\\Anaconda3\\lib\\site-
packages\\pweave\\pweb.py", line '
'192, in weave\n'
' self.run()\n',
' File "G:\\Installed\\Anaconda3\\lib\\site-
packages\\pweave\\pweb.py", line '
'129, in run\n'
' proc.run()\n',
' File '
'"G:\\Installed\\Anaconda3\\lib\\site-
packages\\pweave\\processors\\base.py", '
'line 46, in run\n'
' res = self._runcode(chunk)\n',
' File '
'"G:\\Installed\\Anaconda3\\lib\\site-
packages\\pweave\\processors\\base.py", '
'line 171, in _runcode\n'
" chunk['result'] = self.loadstring(chunk['content'],
chunk=chunk)\n",
' File '
'"G:\\Installed\\Anaconda3\\lib\\site-
packages\\pweave\\processors\\jupyter.py", '
'line 134, in loadstring\n'
' return self.run_cell(code_str)\n',
' File '
'"G:\\Installed\\Anaconda3\\lib\\site-
packages\\pweave\\processors\\jupyter.py", '
'line 58, in run_cell\n'
' msg_id = self.kc.execute(src.lstrip(), store_history=False)\n',
' File '
'"G:\\Installed\\Anaconda3\\lib\\site-
packages\\ipykernel\\inprocess\\client.py", '
'line 102, in execute\n'
' self._dispatch_to_kernel(msg)\n',
' File '
'"G:\\Installed\\Anaconda3\\lib\\site-
packages\\ipykernel\\inprocess\\client.py", '
'line 170, in _dispatch_to_kernel\n'
' kernel.dispatch_shell(stream, msg_parts)\n',
' File "G:\\Installed\\Anaconda3\\lib\\site-
packages\\tornado\\gen.py", line '
'209, in wrapper\n'
' yielded = next(result)\n',
' File '
'"G:\\Installed\\Anaconda3\\lib\\site-
packages\\ipykernel\\kernelbase.py", '
'line 268, in dispatch_shell\n'
' yield gen.maybe_future(handler(stream, idents, msg))\n',
' File '
'"G:\\Installed\\Anaconda3\\lib\\site-
packages\\ipykernel\\inprocess\\ipkernel.py", '
'line 80, in execute_request\n'
' super(InProcessKernel, self).execute_request(stream, ident,
parent)\n',
' File "G:\\Installed\\Anaconda3\\lib\\site-
packages\\tornado\\gen.py", line '
'209, in wrapper\n'
' yielded = next(result)\n',
' File '
'"G:\\Installed\\Anaconda3\\lib\\site-
packages\\ipykernel\\kernelbase.py", '
'line 541, in execute_request\n'
' user_expressions, allow_stdin,\n',
' File "G:\\Installed\\Anaconda3\\lib\\site-
packages\\tornado\\gen.py", line '
'209, in wrapper\n'
' yielded = next(result)\n',
' File '
'"G:\\Installed\\Anaconda3\\lib\\site-
packages\\ipykernel\\ipkernel.py", line '
'300, in do_execute\n'
' res = shell.run_cell(code, store_history=store_history,
silent=silent)\n',
' File '
'"G:\\Installed\\Anaconda3\\lib\\site-
packages\\ipykernel\\zmqshell.py", line '
'536, in run_cell\n'
' return super(ZMQInteractiveShell, self).run_cell(*args,
**kwargs)\n',
' File '
'"G:\\Installed\\Anaconda3\\lib\\site-
packages\\IPython\\core\\interactiveshell.py", '
'line 2858, in run_cell\n'
' raw_cell, store_history, silent, shell_futures)\n',
' File '
'"G:\\Installed\\Anaconda3\\lib\\site-
packages\\IPython\\core\\interactiveshell.py", '
'line 2886, in _run_cell\n'
' return runner(coro)\n',
' File '
'"G:\\Installed\\Anaconda3\\lib\\site-
packages\\IPython\\core\\async_helpers.py", '
'line 68, in _pseudo_sync_runner\n'
' coro.send(None)\n',
' File '
'"G:\\Installed\\Anaconda3\\lib\\site-
packages\\IPython\\core\\interactiveshell.py", '
'line 3063, in run_cell_async\n'
' interactivity=interactivity, compiler=compiler,
result=result)\n',
' File '
'"G:\\Installed\\Anaconda3\\lib\\site-
packages\\IPython\\core\\interactiveshell.py", '
'line 3254, in run_ast_nodes\n'
' if (await self.run_code(code, result, async_=asy)):\n',
' File '
'"G:\\Installed\\Anaconda3\\lib\\site-
packages\\IPython\\core\\interactiveshell.py", '
'line 3331, in run_code\n'
' exec(code_obj, self.user_global_ns, self.user_ns)\n',
' File "<ipython-input-1-175e8d8ff5b6>", line 9, in <module>\n'
' formatted_stack = call_function(f)\n',
' File "<ipython-input-1-8548a9dafead>", line 3, in call_function\n'
' return call_function(f, recursion_level - 1)\n',
' File "<ipython-input-1-8548a9dafead>", line 3, in call_function\n'
' return call_function(f, recursion_level - 1)\n',
' File "<ipython-input-1-8548a9dafead>", line 5, in call_function\n'
' return f()\n',
' File "<ipython-input-1-175e8d8ff5b6>", line 7, in f\n'
' return traceback.format_stack()\n']
extract_stack()
函数与 extract_tb()
差不多。
import traceback
import sys
import os
template = '{filename:<26}:{linenum}:{funcname}:\n {source}'
def f():
return traceback.extract_stack()
stack = call_function(f)
for filename, linenum, funcname, source in stack:
if funcname != '<module>':
funcname = funcname + '()'
print(template.format(
filename=os.path.basename(filename),
linenum=linenum,
source=source,
funcname=funcname)
)
setup_m.py :45:<module>:
save_dir=save_dir)
__init__.py :62:weave():
doc.weave()
pweb.py :192:weave():
self.run()
pweb.py :129:run():
proc.run()
base.py :46:run():
res = self._runcode(chunk)
base.py :171:_runcode():
chunk['result'] = self.loadstring(chunk['content'], chunk=chunk)
jupyter.py :134:loadstring():
return self.run_cell(code_str)
jupyter.py :58:run_cell():
msg_id = self.kc.execute(src.lstrip(), store_history=False)
client.py :102:execute():
self._dispatch_to_kernel(msg)
client.py :170:_dispatch_to_kernel():
kernel.dispatch_shell(stream, msg_parts)
gen.py :209:wrapper():
yielded = next(result)
kernelbase.py :268:dispatch_shell():
yield gen.maybe_future(handler(stream, idents, msg))
ipkernel.py :80:execute_request():
super(InProcessKernel, self).execute_request(stream, ident,
parent)
gen.py :209:wrapper():
yielded = next(result)
kernelbase.py :541:execute_request():
user_expressions, allow_stdin,
gen.py :209:wrapper():
yielded = next(result)
ipkernel.py :300:do_execute():
res = shell.run_cell(code, store_history=store_history,
silent=silent)
zmqshell.py :536:run_cell():
return super(ZMQInteractiveShell, self).run_cell(*args, **kwargs)
interactiveshell.py :2858:run_cell():
raw_cell, store_history, silent, shell_futures)
interactiveshell.py :2886:_run_cell():
return runner(coro)
async_helpers.py :68:_pseudo_sync_runner():
coro.send(None)
interactiveshell.py :3063:run_cell_async():
interactivity=interactivity, compiler=compiler, result=result)
interactiveshell.py :3254:run_ast_nodes():
if (await self.run_code(code, result, async_=asy)):
interactiveshell.py :3331:run_code():
exec(code_obj, self.user_global_ns, self.user_ns)
<ipython-input-1-ff723ef2e674>:11:<module>:
stack = call_function(f)
<ipython-input-1-8548a9dafead>:3:call_function():
return call_function(f, recursion_level - 1)
<ipython-input-1-8548a9dafead>:3:call_function():
return call_function(f, recursion_level - 1)
<ipython-input-1-8548a9dafead>:5:call_function():
return f()
<ipython-input-1-ff723ef2e674>:9:f():
return traceback.extract_stack()
它还可以接受参数,但我们在这里并未使用,该参数的作用是使其从堆栈帧中的其他位置(层级)开始或限制遍历深度。
# https://blog.csdn.net/weixin_43193719/article/details/95518650
# https://www.osgeo.cn/cpython/library/traceback.html
# https://www.jianshu.com/p/a8cb5375171a
# https://groups.google.com/forum/#!topic/python-cn/bJHTBI9vhwc
# https://docs.python.org/3/library/inspect.html
# https://stackoverflow.com/questions/3702675/how-to-print-the-full-traceback-without-halting-the-program