浅谈python出错时traceback的解读


Posted in Python onJuly 15, 2020

写 Python 代码的时候,当代码中出现错误,会在输出的时候打印 Traceback  错误信息,很多初学者看到那一堆错误信息,往往都会处于懵逼状态,脑中总会冒出一句,这都是些啥玩意。如果你是第一次看到它,也许你不知道它在告诉你什么。虽然 Python 的 Traceback  提示信息看着挺复杂,但是里面丰富的信息,可以帮助你诊断和修复代码中引发异常的原因,以及定位到具体哪个文件的哪行代码出现的错误,所以说学会看懂 Traceback  信息是非常重要的,另外在面试的时候也经常会问到 Python 中的异常类型及其含义,那么,接下来就让我们对其进行详细理解。

什么是 Traceback

Traceback 是 Python  错误信息的报告。在其他编程语言中有着不同的叫法包括 stack trace, stack  traceback, backtrac  等名称, 在 Python  中,我们使用的术语是 Traceback。后面我提到的错误信息等词都表示Traceback。
当你的程序导致异常时,Python 将打印 Traceback 以帮助你知道哪里出错了。下面是一个例子来说明这种情况

# example.py
def greet(someone ):
  print('Hello, ' + someon )
 
greet('Chad')

这里首先定义了函数 greet,然后传入参数 someone,然后函数内,一个 print  语句其中 someon  是一个没有定义的变量,然后通过 greet ('Chad'),调用刚才定义的 greet  函数,运行之后会出现如下错误信息。

(Python 中的错误信息开头就是 Traceback。)

Traceback  (most  recent  call  last ):
  File  '/Users/chenxiangan/pythonproject/demo/exmpale.py', line  5, in  <module>
    greet ('Chad')
  File  '/Users/chenxiangan/pythonproject/demo/exmpale.py', line  3, in  greet
    print ('Hello, ' + someon )
NameError: name  'someon' is  not  defined

此错误输出包含诊断问题所需的所有信息。错误输出的最后一行一般会告诉你引发了什么类型的异常,以及关于该异常的一些相关信息。错误信息的前几行指出了引发异常的代码文件以及行数。

在上面的错误信息中,异常类型是 NameError,意思是名称使用了一个没定义的名称(变量、函数、类)的引用。在本例中,引用的名称是 someon。

一般情况下看错误信息的最后一行就能定位到错误的原因。然后在代码中搜索错误提示中的名称'someon',然后发现这是一个拼写错误,然后我们改成 someone  即可。

然而,有些代码的错误信息要比这个复杂的多。

如何阅读 Python 的 Traceback  信息?

当你想确定代码为什么引发异常的时侯,可以根据 Python  的 Traceback  获取许多有用的信息。下面,将列举一些常见的 Traceback,以便理解 Tracebac 中包含的不同信息。

Python Traceback 信息一览

每个 Python 的 Traceback  信息都有几个重要的部分。下图显示了各个组成部分:

  • 蓝框:Traceback 的最后一行为错误消息行。其中包含引发的异常名称。
  • 绿框:异常名称后面是错误消息。此消息通常包含有用的信息,用于了解引发异常的原因。
  • 黄色方框:阅读顺序由下而上,最下面的信息,是抛出错误的最外层的位置,越往上代码调用深度越深。

然后每个出错的文件会有两条错误信息,第一行是 File 后面紧跟着文件的路径,然后是行数,最后是模块或者方法名。
在 Pycharm  中点击文件的链接即可定位到错误的位置。

红色下划线:第二行就是实际执行的代码语句了。

 一个具体的例子

通过一些特定的 Traceback 信息,可以帮助我们更好地理解并查看 Traceback 将提供什么信息。

通过下面的示例代码来说明 Python 中 Traceback 所提供的信息

def who_to_greet(person ):
  return person if person else input ('Greet who? ')

def greet(someone, greeting='Hello'):
  print(greeting + ', ' + who_to_greet (someone ))

def greet_many(people):
  for person in people:
    try:
      greet(person )
    except Exception:
      print ('hi, ' + person )

定义一个 who_to_greet  函数,然后接受一个值 person,并根据 if  判断返回相应结果。

然后,greet  函数接受一个 someone 和一个可选的 greeting,之后调用 print  函数,在 print 中调用 who_to_greet 函数并传入参数 someone。

最后,greet_many(),将迭代 people  列表并调用 greet 函数。如果通过调用 greet()引发异常,则会打印一个简单的问候语。

只要提供了正确的输入,此代码就没有任何可能导致异常被引发的错误。

如果你在 greetings.py  中调用 greet 函数,并传入值(例如 greet ('chad',greting ='Yo')),那么你将获得以下 Traceback  信息

Traceback  (most  recent  call  last ):
  File  '/Users/chenxiangan/pythonproject/demo/greetings.py', line  17, in  <module>
    greet ('chad',greting  ='Yo')
TypeError: greet () got  an  unexpected  keyword  argument  'greting'

之前我们说过阅读 Python 的 Traceback  信息,是由下而上进行阅读的,这里我们再一起看一看。

首先,我们需要看的是错误信息的最后一行,通过最后一行可以知道错误的类型以及一些错误原因。

意思是说:调用 greet()的时候使用了一个未知的参数,这个未知参数就是 greting。

好的,然后我们需要继续向上看,可以看到导致异常的行。在这个例子中我们看到的是调用 greet 方法的具体代码。

它的上一行提供了代码所在文件的路径,以及代码文件的行号以及它所在的模块。(Pycharm 中通过点击文件链接可以定位到具体位置)

在这个例子中,因为我们的代码没有使用任何其他 Python  模块,所以我们在这里看到<module>,它表示所处位置是在执行的文件。

使用不同的文件和不同的调用方式调用 greet 方法,得到的 Traceback  信息也是不同的,下面就通过文件导入的形式来执行 greet 方法。看看结果有什么区别吧

# example.py 
from greetings import greet 
greet (1)

运行之后的结果:

Traceback  (most  recent  call  last ):
  File  '/Users/chenxiangan/pythonproject/demo/exmpale.py', line  3, in  <module>
    greet (1)
  File  '/Users/chenxiangan/pythonproject/demo/greetings.py', line  6, in  greet
    print (greeting  + ', ' + who_to_greet (someone ))
TypeError: can  only  concatenate  str  (not  'int') to  str

在本例中引发的异常同样是一个类型错误,但这一次消息的帮助要小一些。它只是告诉你,在代码的某个地方,字符串只能和字符串拼接,不能是 int。

向上移动,可以看到执行的代码行。然后是文件和行号的代码。不过,这一次我们得到的不是,而是正在执行的函数的名称 greet()。

然后继续往上看,一行执行的代码,我们看到问题代码是 greet()函数调用时传入了一个整数。

有时在引发异常之后,另一部分代码会捕获该异常并导致异常。在这种情况下,Python 将按接收顺序输出所有异常信息,最外层的异常信息处于 Traceback 内容的最下面位置。

可能看起来有点懵,下面使用一个具体例子进行说明。

在 greetings.py  文件中调用 greet_many  方式具体调用代码如下:

greet_many (['Chad', 'Dan', 1])

运行之后输出的错误信息如下

Hello, Chad
Hello, Dan
Traceback  (most  recent  call  last ):
  File  '/Users/chenxiangan/pythonproject/demo/greetings.py', line  12, in  greet_many
    greet (person )
  File  '/Users/chenxiangan/pythonproject/demo/greetings.py', line  6, in  greet
    print (greeting  + ', ' + who_to_greet (someone ))
TypeError: can  only  concatenate  str  (not  'int') to  str

During  handling  of  the  above  exception, another  exception  occurred:

Traceback  (most  recent  call  last ):
  File  '/Users/chenxiangan/pythonproject/demo/greetings.py', line  17, in  <module>
    greet_many (['Chad', 'Dan', 1])
  File  '/Users/chenxiangan/pythonproject/demo/greetings.py', line  14, in  greet_many
    print ('hi, ' + person )
TypeError: can  only  concatenate  str  (not  'int') to  str

emmmmm,这次好像不太一样,比之前的内容多了不少,而且有两个 Traceback 块信息,这是什么意思呢?

注意这句话

During  handling  of  the  above  exception, another  exception  occurred:

它的意思是:在处理上述异常期间,发生了另一个异常。简单理解就是在 except 中的代码出现了异常。所以导致了这种现象。

这个例子就是在第三次循环的时候 person=1 然后字符串 hi  和1 不能进行拼接操作,然后再次引发了异常。

查看所有的错误信息输出可以帮助您了解异常的真正原因。

有时,当您看到最后一个异常被引发,并由此产生错误信息时,你可能仍然看不出哪里出错了。比如这例子,直接通过最后的异常看不到问题具体出在哪,这个时候就要考虑继续往上看了。

到此这篇关于浅谈python出错时traceback的解读的文章就介绍到这了,更多相关python traceback内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python计算文本文件行数的方法
Jul 06 Python
Python的Scrapy爬虫框架简单学习笔记
Jan 20 Python
Python 中迭代器与生成器实例详解
Mar 29 Python
Python设计实现的计算器功能完整实例
Aug 18 Python
Python基于正则表达式实现检查文件内容的方法【文件检索】
Aug 30 Python
Python开发中爬虫使用代理proxy抓取网页的方法示例
Sep 26 Python
python使用jieba实现中文分词去停用词方法示例
Mar 11 Python
python+pandas生成指定日期和重采样的方法
Apr 11 Python
python中for循环输出列表索引与对应的值方法
Nov 07 Python
python读取几个G的csv文件方法
Jan 07 Python
OpenCV Python实现拼图小游戏
Mar 23 Python
Python迭代器协议及for循环工作机制详解
Jul 14 Python
Django视图、传参和forms验证操作
Jul 15 #Python
一文解决django 2.2与mysql兼容性问题
Jul 15 #Python
django 模型字段设置默认值代码
Jul 15 #Python
django序列化时使用外键的真实值操作
Jul 15 #Python
Django:使用filter的pk进行多值查询操作
Jul 15 #Python
django models里数据表插入数据id自增操作
Jul 15 #Python
python报错: 'list' object has no attribute 'shape'的解决
Jul 15 #Python
You might like
中东人咖啡哲学
2021/03/03 咖啡文化
drupal 代码实现URL重写
2011/05/04 PHP
php采集神器cURL使用方法详解
2016/02/19 PHP
JavaScript 核心参考教程 内置对象
2009/10/13 Javascript
js 获取Listbox选择的值的代码
2010/04/15 Javascript
JQuery index()方法使用代码
2010/06/02 Javascript
Jquery实现兼容各大浏览器的Enter回车切换输入焦点的方法
2014/09/01 Javascript
Jquery与Bootstrap实现后台管理页面增删改查功能示例
2017/01/22 Javascript
Angular 4中如何显示内容的CSS样式示例代码
2017/11/06 Javascript
mui框架 页面无法滚动的解决方法(推荐)
2018/01/25 Javascript
vue多页面开发和打包正确处理方法
2018/04/20 Javascript
浅谈vue中.vue文件解析流程
2018/04/24 Javascript
浅谈Vue响应式(数组变异方法)
2018/05/07 Javascript
vue使用微信JS-SDK实现分享功能
2019/08/23 Javascript
jquery实现点击弹出对话框
2020/02/08 jQuery
[44:15]国士无双DOTA2 6.82版本详解(上)
2014/09/28 DOTA
Python获取电脑硬件信息及状态的实现方法
2014/08/29 Python
深入理解Python中各种方法的运作原理
2015/06/15 Python
Python的Django框架中使用SQLAlchemy操作数据库的教程
2016/06/02 Python
Python三级目录展示的实现方法
2016/09/28 Python
Python实现将数据库一键导出为Excel表格的实例
2016/12/30 Python
老生常谈python的私有公有属性(必看篇)
2017/06/09 Python
Python3简单爬虫抓取网页图片代码实例
2019/08/26 Python
django2.2 和 PyMySQL版本兼容问题
2020/02/17 Python
python实现代码审查自动回复消息
2021/02/01 Python
Canvas 文本转粒子效果的实现代码
2019/02/14 HTML / CSS
.NET面试问题集
2015/12/08 面试题
转让协议书范本
2014/09/13 职场文书
群众路线教育实践活动批评与自我批评
2014/09/15 职场文书
大学生自我评价200字(4篇)
2014/09/17 职场文书
党员检讨书范文
2014/12/27 职场文书
初三语文教学计划
2015/01/22 职场文书
酒店客房服务员岗位职责
2015/04/09 职场文书
校园歌手大赛主持词
2015/07/03 职场文书
小学四年级班主任工作经验交流材料
2015/11/02 职场文书
深入浅析Redis 集群伸缩原理
2021/05/15 Redis