python – 使用库时缩短大型堆栈跟踪
我经常使用像
pandas或
matplotlib这样的大型库.
这意味着异常通常会产生长堆栈跟踪. 由于库中的错误极少,并且经常使用我自己的代码,因此在绝大多数情况下我都不需要查看库的详细信息. 一些常见的例子: 熊猫 >>> import pandas as pd >>> df = pd.DataFrame(dict(a=[1,2,3])) >>> df['b'] # Hint: there _is_ no 'b' 在这里,我试图访问一个未知的密钥.这个简单的错误会产生一个包含28行的堆栈跟踪: Traceback (most recent call last): File "an_arbitrary_pythonlibsite-packagespandascoreindexesbase.py",line 2393,in get_loc return self._engine.get_loc(key) File "pandas_libsindex.pyx",line 132,in pandas._libs.index.IndexEngine.get_loc (pandas_libsindex.c:5239) File "pandas_libsindex.pyx",line 154,in pandas._libs.index.IndexEngine.get_loc (pandas_libsindex.c:5085) File "pandas_libshashtable_class_helper.pxi",line 1207,in pandas._libs.hashtable.PyObjectHashTable.get_item (pandas_libshashtable.c:20405) File "pandas_libshashtable_class_helper.pxi",line 1215,in pandas._libs.hashtable.PyObjectHashTable.get_item (pandas_libshashtable.c:20359) KeyError: 'b' During handling of the above exception,another exception occurred: Traceback (most recent call last): File "<stdin>",line 1,in <module> File "an_arbitrary_pythonlibsite-packagespandascoreframe.py",line 2062,in __getitem__ return self._getitem_column(key) File "an_arbitrary_pythonlibsite-packagespandascoreframe.py",line 2069,in _getitem_column return self._get_item_cache(key) File "an_arbitrary_pythonlibsite-packagespandascoregeneric.py",line 1534,in _get_item_cache values = self._data.get(item) File "an_arbitrary_pythonlibsite-packagespandascoreinternals.py",line 3590,in get loc = self.items.get_loc(item) File "an_arbitrary_pythonlibsite-packagespandascoreindexesbase.py",line 2395,in get_loc return self._engine.get_loc(self._maybe_cast_indexer(key)) File "pandas_libsindex.pyx",in pandas._libs.index.IndexEngine.get_loc (pandas_libsindex.c:5239) File "pandas_libsindex.pyx",in pandas._libs.index.IndexEngine.get_loc (pandas_libsindex.c:5085) File "pandas_libshashtable_class_helper.pxi",in pandas._libs.hashtable.PyObjectHashTable.get_item (pandas_libshashtable.c:20405) File "pandas_libshashtable_class_helper.pxi",in pandas._libs.hashtable.PyObjectHashTable.get_item (pandas_libshashtable.c:20359) KeyError: 'b' 知道我最终在hashtable_class_helper.pxi中对我来说几乎没用.我需要知道我的代码在哪里搞砸了. Matplotlib >>> import matplotlib.pyplot as plt >>> import matplotlib.cm as cm >>> def foo(): ... plt.plot([1,3],cbap=cm.Blues) # cbap is a typo for cmap ... >>> def bar(): ... foo() ... >>> bar() 这一次,我的关键字参数中有一个拼写错误.但我仍然需要看到25行堆栈跟踪: Traceback (most recent call last): File "<stdin>",in <module> File "<stdin>",line 2,in bar File "<stdin>",in foo File "an_arbitrary_pythonlibsite-packagesmatplotlibpyplot.py",line 3317,in plot ret = ax.plot(*args,**kwargs) File "an_arbitrary_pythonlibsite-packagesmatplotlib__init__.py",line 1897,in inner return func(ax,*args,**kwargs) File "an_arbitrary_pythonlibsite-packagesmatplotlibaxes_axes.py",line 1406,in plot for line in self._get_lines(*args,**kwargs): File "an_arbitrary_pythonlibsite-packagesmatplotlibaxes_base.py",line 407,in _grab_next_args for seg in self._plot_args(remaining,kwargs): File "an_arbitrary_pythonlibsite-packagesmatplotlibaxes_base.py",line 395,in _plot_args seg = func(x[:,j % ncx],y[:,j % ncy],kw,kwargs) File "an_arbitrary_pythonlibsite-packagesmatplotlibaxes_base.py",line 302,in _makeline seg = mlines.Line2D(x,y,**kw) File "an_arbitrary_pythonlibsite-packagesmatplotliblines.py",line 431,in __init__ self.update(kwargs) File "an_arbitrary_pythonlibsite-packagesmatplotlibartist.py",line 885,in update for k,v in props.items()] File "an_arbitrary_pythonlibsite-packagesmatplotlibartist.py",in <listcomp> for k,line 878,in _update_property raise AttributeError('Unknown property %s' % k) AttributeError: Unknown property cbap 在这里,我发现我在artist.py中的一行引发了一个引发AttributeError的行,然后直接看到它确实引发了AttributeError.这在信息术语中没有多大价值. 在这些琐碎,互动的例子中,你可能只是说“看看堆栈顶部而不是底部”,但通常我的愚蠢错字发生在一个函数中,所以我感兴趣的行是在某处的中间位置这些库杂乱的堆栈跟踪. 有什么方法可以让这些堆栈跟踪更简洁,并帮助我找到问题的根源,这几乎总是在我自己的代码中,而不是在我碰巧使用的库中? 解决方法
您可以使用
traceback更好地控制异常打印.例如:
import pandas as pd import traceback try: df = pd.DataFrame(dict(a=[1,3])) df['b'] except Exception,e: traceback.print_exc(limit=1) exit(1) 这会触发标准异常打印机制,但只显示堆栈跟踪的第一帧(在您的示例中是您关注的那个).这对我来说产生: Traceback (most recent call last): File "t.py",line 6,in <module> df['b'] KeyError: 'b' 显然你会丢失上下文,这在调试自己的代码时很重要.如果我们想要获得幻想,我们可以尝试设计一个测试,看看回溯应该走多远.例如: def find_depth(tb,continue_test): depth = 0 while tb is not None: filename = tb.tb_frame.f_code.co_filename # Run the test we're given against the filename if not continue_test(filename): return depth tb = tb.tb_next depth += 1 我不知道你是如何组织和运行你的代码的,但也许你可以这样做: import pandas as pd import traceback import sys def find_depth(): # ... code from above here ... try: df = pd.DataFrame(dict(a=[1,e: traceback.print_exc(limit=get_depth( sys.exc_info()[2],# The test for which frames we should include lambda filename: filename.startswith('my_module') )) exit(1) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |