代码之家  ›  专栏  ›  技术社区  ›  jason

python:如何在我的代码最后一次出错之前起床

  •  6
  • jason  · 技术社区  · 8 年前

    所以当我运行这个…错误在这一行 bomb=pd.DataFrame(here,0) 但跟踪显示了 pandas 要获取错误的库。

    import traceback,sys
    import pandas as pd        
    
    def error_handle(err_var,instance_name=None): #err_var list of variables, instance_name
        print(traceback.format_exc())
        a= sys._getframe(1).f_locals
    
        for i in err_var: # selected var for instance
            t= a[instance_name]
            print i,"--->",getattr(t,i.split(".")[1])
    
    
    
    here=['foo']
    
    err_var = ['self.needthisone','self.constant2']
    class test:
    
        def __init__(self):
            self.constant1 = 'hi1'
            #self.constant2 = 'hi2'
            #self.needthisone = ':)'
            for i in err_var:
                setattr(self, i.split('.')[1], None)
    
        def other_function(self):
            self.other_var=5
    
        def testing(self):
            self.other_function()
            vars=[self.constant1,self.constant2]
    
            try:
                for i in vars: 
                    bomb=pd.DataFrame(here,0)
    
            except:
                error_handle(err_var,'self')
    
    t=test()
    t.testing()    
    

    如何抑制所有这些并使错误看起来像这样:

    Traceback (most recent call last):
      File "C:\Users\Jason\Google Drive\python\error_handling.py", line 34, in testing
        bomb=pd.DataFrame(here,0)
    TypeError: Index(...) must be called with a collection of some kind, 0 was passed
    

    我只想知道与我相关的内容,以及我写的最后一行糟糕的代码。

    这是原版:

    Traceback (most recent call last):
      File "C:\Users\Jason\Google Drive\python\error_handling.py", line 35, in testing
        bomb=pd.DataFrame(here,0)
      File "C:\Python27\lib\site-packages\pandas\core\frame.py", line 330, in __init__
        copy=copy)
      File "C:\Python27\lib\site-packages\pandas\core\frame.py", line 474, in _init_ndarray
        index, columns = _get_axes(*values.shape)
      File "C:\Python27\lib\site-packages\pandas\core\frame.py", line 436, in _get_axes
        index = _ensure_index(index)
      File "C:\Python27\lib\site-packages\pandas\core\indexes\base.py", line 3978, in _ensure_index
        return Index(index_like)
      File "C:\Python27\lib\site-packages\pandas\core\indexes\base.py", line 326, in __new__
        cls._scalar_data_error(data)
      File "C:\Python27\lib\site-packages\pandas\core\indexes\base.py", line 678, in _scalar_data_error
        repr(data)))
    TypeError: Index(...) must be called with a collection of some kind, 0 was passed
    
    self.needthisone ---> None
    self.constant2 ---> None
    
    3 回复  |  直到 8 年前
        1
  •  2
  •   Chen A.    7 年前

    我非常鼓励你 不限制回溯输出 因为这是不好的做法。你觉得信息太多了,但这仅仅是因为你已经看过了,你知道要寻找什么样的错误。

    在大多数情况下,问题可能隐藏在其他地方。 所以必须有更好的方法来实现你所期待的。

    为什么不将函数调用包装在 try except 子句并打印异常消息?以这个场景为例:

    def f():
        a = 0
        i = 1
        print i/a
    
    def another_func():
        print 'this is another func'
        return f()
    
    def higher_level_func():
        print 'this is higher level'
        return another_func()
    
    
    if __name__ == '__main__':
        try:
            higher_level_func()
        except Exception as e:
            print 'caught the exception: {}-{}'.format(type(e)__name__, e.message)
    

    调用时,这是输出:

    this is higher level
    this is another func
    caught the exception: ZeroDivisionError-integer division or modulo by zero
    

    这将只打印代码中的相关异常,隐藏有关跟踪的任何信息,但跟踪仍然可用,您也可以打印它(只需从except块中引发异常)。

    与此相比,如果我移除 尝试除外 块:

    this is higher level
    this is another func
    caught the exception: integer division or modulo by zero
    Traceback (most recent call last):
      File "test.py", line 17, in <module>
        higher_level_func()
      File "test.py", line 12, in higher_level_func
        return another_func()
      File "test.py", line 8, in another_func
        return f()
      File "test.py", line 4, in f
        print i/a
    ZeroDivisionError: integer division or modulo by zero
    

    您最好使用此技术捕获相关的异常,而不是限制回溯。如果您想停止程序,只需添加 sys.exit(1) except 块。

        2
  •  4
  •   GetHacked    8 年前

    您可以使用 sys.traceback 变量。如果您的代码只有3层深度(文件中类中的函数),那么您可以使用代码适当地定义这一点:

    sys.tracebacklimit = 3
    

    在文件的顶部。 小心这个 :当您编写更多的代码时,您所编写的部分将变得越来越深,并且您可能很快就会发现错误是由更深层的回溯造成的。作为一般规则,我将避免使用变量,只是暂时处理较长的回溯。

        3
  •  4
  •   rsalmei    7 年前

    请不要考虑限制堆栈跟踪。这是非常重要的。 只有在此时,在您的这个小例子中,错误才真正出现在您的代码中。

    但在其他无限多的情况下,一个错误可能会触发的更深。它可能在框架中,甚至是任何代码之外,比如配置错误,也可能在平台中,比如内存不足错误等等。

    堆栈跟踪可以帮助您。它列出了编译器正在执行的所有帧,为您提供理解所发生的事情所需的所有信息。