加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python – 使用库时缩短大型堆栈跟踪

发布时间:2020-12-20 13:19:28 所属栏目:Python 来源:网络整理
导读:我经常使用像 pandas或 matplotlib这样的大型库. 这意味着异常通常会产生长堆栈跟踪. 由于库中的错误极少,并且经常使用我自己的代码,因此在绝大多数情况下我都不需要查看库的详细信息. 一些常见的例子: 熊猫 import pandas as pd df = pd.DataFrame(dict(a=
我经常使用像 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)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读