大家好,今天给各位分享接码网站全套源码分享的一些知识,其中也会对接码网站怎么用进行解释,文章篇幅可能偏长,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在就马上开始吧!
作者|ChadHansen
来源|Python学习开发
英文|UnderstandingthePythonTraceback–RealPython
在写Python代码的时候,当代码中出现错误,会在输出的时候打印Traceback错误信息,很多初学者看到那一堆错误信息,往往都会处于懵逼状态,脑中总会冒出一句,这都是些啥玩意。如果你是第一次看到它,也许你不知道它在告诉你什么。虽然Python的Traceback提示信息看着挺复杂,但是里面丰富的信息,可以帮助你诊断和修复代码中引发异常的原因,以及定位到具体哪个文件的哪行代码出现的错误,所以说学会看懂Traceback信息是非常重要的,另外在面试的时候也经常会问到Python中的异常类型及其含义,那么,接下来就让我们对其进行详细理解。
什么是Traceback
Traceback是Python错误信息的报告。在其他编程语言中有着不同的叫法包括stacktrace,stacktraceback,backtrac等名称,在Python中,我们使用的术语是Traceback。后面我提到的错误信息等词都表示Traceback。
当你的程序导致异常时,Python将打印Traceback以帮助你知道哪里出错了。下面是一个例子来说明这种情况
example.py\nfromgreetingsimportgreet\ngreet(1)\n
运行之后的结果
Traceback(mostrecentcalllast):\nFile”/Users/chenxiangan/pythonproject/demo/exmpale.py”,line3,in<module>\ngreet(1)\nFile”/Users/chenxiangan/pythonproject/demo/greetings.py”,line6,ingreet\nprint(greeting+’,’+who_to_greet(someone))\nTypeError:canonlyconcatenatestr(not”int”)tostr\n
在本例中引发的异常同样是一个类型错误,但这一次消息的帮助要小一些。它只是告诉你,在代码的某个地方,字符串只能和字符串拼接,不能是int。
向上移动,可以看到执行的代码行。然后是文件和行号的代码。不过,这一次我们得到的不是,而是正在执行的函数的名称greet()。
然后继续往上看,一行执行的代码,我们看到问题代码是greet()函数调用时传入了一个整数。
有时在引发异常之后,另一部分代码会捕获该异常并导致异常。在这种情况下,Python将按接收顺序输出所有异常信息,最外层的异常信息处于Traceback内容的最下面位置。
可能看起来有点懵,下面使用一个具体例子进行说明。
在greetings.py文件中调用greet_many方式具体调用代码如下:
greet_many([‘Chad’,’Dan’,1])\n
运行之后输出的错误信息如下
Hello,Chad\nHello,Dan\nTraceback(mostrecentcalllast):\nFile”/Users/chenxiangan/pythonproject/demo/greetings.py”,line12,ingreet_many\ngreet(person)\nFile”/Users/chenxiangan/pythonproject/demo/greetings.py”,line6,ingreet\nprint(greeting+’,’+who_to_greet(someone))\nTypeError:canonlyconcatenatestr(not”int”)tostr\nDuringhandlingoftheaboveexception,anotherexceptionoccurred:\nTraceback(mostrecentcalllast):\nFile”/Users/chenxiangan/pythonproject/demo/greetings.py”,line17,in<module>\ngreet_many([‘Chad’,’Dan’,1])\nFile”/Users/chenxiangan/pythonproject/demo/greetings.py”,line14,ingreet_many\nprint(‘hi,’+person)\nTypeError:canonlyconcatenatestr(not”int”)tostr\n
emmmmm,这次好像不太一样,比之前的内容多了不少,而且有两个Traceback块信息,这是什么意思呢?
注意这句话
Duringhandlingoftheaboveexception,anotherexceptionoccurred:\n
它的意思是:在处理上述异常期间,发生了另一个异常。简单理解就是在except中的代码出现了异常。所以导致了这种现象。
这个例子就是在第三次循环的时候person=1然后字符串hi和1不能进行拼接操作,然后再次引发了异常。
查看所有的错误信息输出可以帮助您了解异常的真正原因。
有时,当您看到最后一个异常被引发,并由此产生错误信息时,
你可能仍然看不出哪里出错了。比如这例子,直接通过最后的异常看不到问题具体出在哪,这个时候就要考虑继续往上看了。
Python中有哪些常见的异常类型
在编程时,知道如何在程序引发异常时读取Python异常信息非常有用,如果再了解一些常见的异常类型那就更好了。
有时候在面试的时候也会遇到提问Python中常见的异常类型,以及其含义,所以这里也建议大家都了解以下。
下面就列举一些出现频次高而且非常重要的异常类型,希望大家能够有一定的印象。
AttributeError
当你访问一个对象的属性,但是这个属性并没有在这个对象定义的时候,就会引发AttributeError。
下面是一个引发AttributeError异常的示例:
a=1\na.b\n
运行之后引发异常
Traceback(mostrecentcalllast):\nFile”/Users/chenxiangan/pythonproject/demo/exmpale.py”,line2,in<module>\na.b\nAttributeError:’int’objecthasnoattribute’b’\n
AttributeError的错误消息行告诉我们特定对象类型(在本例中为int)没有访问的属性,
在这个例子中属性为b。点击文件链接可以快速定位到具体的错误代码的位置。
大多数情况下,引发这个异常表明你正在处理的对象可能不是你期望的类型。
a_list=(1,2)\na_list.append(3)\n
运行之后抛出异常信息
Traceback(mostrecentcalllast):\nFile”/Users/chenxiangan/pythonproject/demo/exmpale.py”,line2,in<module>\na_list.append(3)\nAttributeError:’tuple’objecthasnoattribute’append’\n
这里尝试给a_list对象进行append操作但是引发了异常,
这里的错误信息说,tuple对象没有append属性。
原因就是以为a_list是列表但是实际上它是元组,
元组是不可变类型不支持添加元素操作所以出错了。这里也告诉大家,以后定义变量名的时候也要主要规范问题,否则就容易出现这种,期望类型错误的情况。
还有一种情况就是当对None进行属性操作的时候,很容易引发上面的异常
a_list=None\na_list.append(3)\n
运行抛出异常
Traceback(mostrecentcalllast):\nFile”/Users/chenxiangan/pythonproject/demo/exmpale.py”,line2,in<module>\na_list.append(3)\nAttributeError:’NoneType’objecthasnoattribute’append’\n
是不是很眼熟啊,遇到这种情况不要慌,分析看看你的哪个对象是None就好了。
ImportError
在使用import导入模块时,如果要导入的模块找不到,或者从模块中导入模块中不存在的内容。这时就会触发ImportError类型的错误或者它的子类ModuleNotFoundError。
importaaa\n
运行后输出
Traceback(mostrecentcalllast):\nFile”/Users/chenxiangan/pythonproject/demo/exmpale.py”,line1,in<module>\nimportaaa\nModuleNotFoundError:Nomodulenamed’aaa’\n
在这个例子中可以看到,当我们使用import导入一个不存在的模块时,就会出现ModuleNotFoundError的错误,Traceback最下面一句信息给出了原因,
没有名为aaa的模块.
然后我们再运行一个例子
fromcollectionsimportasdf\n
运行之后的内容
Traceback(mostrecentcalllast):\nFile”/Users/chenxiangan/pythonproject/demo/exmpale.py”,line1,in<module>\nfromcollectionsimportasdf\nImportError:cannotimportname’asdf’from’collections’\n
根据前面的经验我们可以得知原因,不能从collections模块中导入名为asdf的模块。
有时候为了程序能兼容在各个系统的时候,如果一个包找不到,找另一个的时候,比如在windows中不能使用ujson,uvloop这两个包,但是在unix系统上是可以运行的,这个时候我们就可以使用下面的方法。
try:\nimportujsonasjson\nexceptImportErrorase:\nimportjson\n
首先导入ujson然后使用as给他重命名为json,如果出现错误就会进入except模块
然后导入标准库的json包,因为这边的库名已经叫json了所以不用再重命名了。记住这个技巧非常的有用哦。
IndexError
当你尝试从序列(如列表或元组)中检索索引,但是序列中找不到该索引。此时就会引发IndexError。
例如
a_list=[‘a’,’b’]\na_list[3]\n
运行之后的结果
Traceback(mostrecentcalllast):\nFile”/Users/chenxiangan/pythonproject/demo/exmpale.py”,line2,in<module>\na_list[3]\nIndexError:listindexoutofrange\n
通过IndexError的错误消息的最后一不能得到一个准确的信息,只知道一个超出范围的序列引用以及序列的类型,在本例中是一个列表。我们需要往上阅读错误信息,才能确定错误的具体位置。这里我们得知错误代码是a_list[3]原因是索引3超出了列表的范围,因为最大就是1(索引下标从0开始的)。
KeyError
与IndexError类似,当你访问映射(通常是dict)中不包含的键时,就会引发KeyError。
a_dict={}\na_dict[‘b’]\n
运行之后
Traceback(mostrecentcalllast):\nFile”/Users/chenxiangan/pythonproject/demo/exmpale.py”,line2,in<module>\na_dict[‘b’]\nKeyError:’b’\n
KeyError的错误消息行给出找不到关键字b。并没有太多的内容,但是,结合上面的错误信息,就可以解决这个问题。
NameError
当你引用了变量、模块、类、函数或代码中没有定义的其他名称时,将引发NameError。
defgreet(person):\nprint(f’Hello,{persn}’)\ngreet(‘World’)\n
运行之后
Traceback(mostrecentcalllast):\nFile”/Users/chenxiangan/pythonproject/demo/exmpale.py”,line3,in<module>\ngreet(‘World’)\nFile”/Users/chenxiangan/pythonproject/demo/exmpale.py”,line2,ingreet\nprint(f’Hello,{persn}’)\nNameError:name’persn’isnotdefined\n
NameErrortraceback的错误消息行给出了缺失的名称persn。
这个例子中,在print使用了没有定义过的变量persn所以出现了错误。
一般在拼写变量名出现问题时会引发这种错误。
SyntaxError
当代码中有不正确的Python语法时,就会引发SyntaxError。
下面的问题是函数定义行末尾缺少一个冒号。
defgreet(person)\n
运行之后
File”/Users/chenxiangan/pythonproject/demo/exmpale.py”,line1\ndefgreet(person)\n^\nSyntaxError:invalidsyntax\n
SyntaxError的错误消息行只告诉你代码的语法有问题。查看上面的行才能得到问题所在的行,通常会用一个^(插入符号)指向问题点。
此外,细心的朋友会注意到,在SyntaxError异常内容的第一行没有了之前的(mostrecentcalllast)。
这是因为SyntaxError是在Python尝试解析代码时引发的,实际上代码并没有执行。
TypeError
当你的代码试图对一个无法执行此操作的对象执行某些操作时,例如将字符串添加到整数中,以及一开始的例子使用append方法给元组添加元素,这些都会引发TypeError。
以下是引发TypeError的几个示例:
>>>1+’1’\nTraceback(mostrecentcalllast):\nFile”<stdin>”,line1,in<module>\nTypeError:unsupportedoperandtype(s)for+:’int’and’str’\n>>>’1’+1\nTraceback(mostrecentcalllast):\nFile”<stdin>”,line1,in<module>\nTypeError:mustbestr,notint\n>>>len(1)\nTraceback(mostrecentcalllast):\nFile”<stdin>”,line1,in<module>\nTypeError:objectoftype’int’hasnolen()\n
以上所有引发类型错误的示例都会产生包含不同消息的错误消息行。它们每一个都能很好地告诉你哪里出了问题。
前两个示例尝试将字符串和整数相加。然而,它们有细微的不同
第一个是尝试在int中拼接一个str。第二个是尝试在str中拼接一个int。
错误消息行反映了这些差异。
最后一个示例尝试在int上调用len()。
错误消息行告诉我们不能使用int执行此操作。
ValueError
当对象的值不正确时就会引发ValueError。这个和我们前面说的因为索引的值不在序列的范围内,而导致IndexError异常类似。
下面看两个例子
>>>a,b,c=[1,2]\nTraceback(mostrecentcalllast):\nFile”<stdin>”,line1,in<module>\nValueError:notenoughvaluestounpack(expected3,got2)\n>>>a,b=[1,2,3]\nTraceback(mostrecentcalllast):\nFile”<stdin>”,line1,in<module>\nValueError:toomanyvaluestounpack(expected2)\n
这些示例中的ValueError错误消息行可以准确地告诉我们值的一些问题:
在第一个示例中,错误信息行是没有足够多的值去unpack(解包)。括号理面详细的写了你希望解包3个值但实际上只给了2个。
第二个示例中,错误信息行是解包太多的值。先解包3个值但是只给了2个变量,所以括号里提示expected2就是说期望的实际是解包2个值。
上面这些错误类型,基本上都是基础遇到的,希望大家能熟悉记忆。
如何记录这些错误信息呢?
前面我们说了很多异常的相关知识,但是我们应该如何利用好呢,这里我们就重点说一下,如何通过记录异常信息,方便后期程序的调试。
下面让我们看一个关于使用requests模块的例子。
首先需要导入requests包,使用pip即可。
importrequests\nurl=”http://wwww.baidu.com”\nresponse=requests.get(url)\nprint(response.status_code,response.text)\n
这是一个访问百度的例子,运行之后,我们成功获取了他的状态码和网页源码。
接下来我们对url进行修改然后再运行。
importrequests\nurl=”http://urlis233.com”\nresponse=requests.get(url)\nprint(response.status_code,response.text)\n
运行之后我们发现程序出现了错误,下面分析下这些错误信息
省略前面部分\nDuringhandlingoftheaboveexception,anotherexceptionoccurred:\nTraceback(mostrecentcalllast):\nFile”/Users/chenxiangan/pythonproject/demo/exmpale.py”,line3,in<module>\nresponse=requests.get(url)\nFile”/Users/chenxiangan/pythonproject/demo/venv/lib/python3.7/site-packages/requests/api.py”,line75,inget\nreturnrequest(‘get’,url,params=params,**kwargs)\nFile”/Users/chenxiangan/pythonproject/demo/venv/lib/python3.7/site-packages/requests/api.py”,line60,inrequest\nreturnsession.request(method=method,url=url,**kwargs)\nFile”/Users/chenxiangan/pythonproject/demo/venv/lib/python3.7/site-packages/requests/sessions.py”,line533,inrequest\nresp=self.send(prep,**send_kwargs)\nFile”/Users/chenxiangan/pythonproject/demo/venv/lib/python3.7/site-packages/requests/sessions.py”,line646,insend\nr=adapter.send(request,**kwargs)\nFile”/Users/chenxiangan/pythonproject/demo/venv/lib/python3.7/site-packages/requests/adapters.py”,line516,insend\nraiseConnectionError(e,request=request)\nrequests.exceptions.ConnectionError:HTTPConnectionPool(host=’urlis233.com’,port=80):Maxretriesexceededwithurl:/(CausedbyNewConnectionError(‘<urllib3.connection.HTTPConnectionobjectat0x10faeba90>:Failedtoestablishanewconnection:[Errno8]nodenamenorservnameprovided,ornotknown’))\n
这个错误信息很长,它引发了许多其他的异常,最终的异常类型是requests.exceptions.ConnectionError。
往前面的错误信息找可以发现问题代码,
File”/Users/chenxiangan/pythonproject/demo/exmpale.py”,line3,in<module>\nresponse=requests.get(url)\n
进而定位到错误,这个错误原因主要是不存在地址”http://urlis233.com”,所以访问失败。
错误我们清楚了,但是一大堆的错误信息搭载控制台上,这样看很不美观,而且因为异常的原因我们的程序中断了。这个时候我们就可以使用Python中的异常处理模块try/except将代码改成下面这样
importrequests\nurl=”http://urlis233.com”\ntry:\nresponse=requests.get(url)\nexceptrequests.exceptions.ConnectionError:\nprint(“-1″,”链接有问题,访问失败”)\nelse:\nprint(response.status_code,response.text)\n
再次运行可以得到下面的结果
-1链接有问题,访问失败\n
ok,我们的程序可以正常运行了,输出的信息也美观了。
但是,在大多数实际系统中,我们不希望只是打印捕获的错误信息到控制台上,而是希望记录这些信息,方便后面的错误排查,所以最好的方案就是通过日志的方式记录这些程序中的异常。
你可以通过导入logging模块,记录这些错误,最终代码如下
importlogging\nimportrequests\nlogger=logging.getLogger(__name__)\nurl=”http://urlis233.com”\ntry:\nresponse=requests.get(url)\nexceptrequests.exceptions.ConnectionErrorase:\nlogger.exception()\nprint(-1,’链接有问题,访问失败’)\nelse:\nprint(response.status_code,response.content)\n
现在,当你再运行有问题的URL的脚本时,不仅会打印错误,同时还会在日志文件中记录这些错误信息。过于日志的其他信息可以看我之前的文章。
关于接码网站全套源码分享,接码网站怎么用的介绍到此结束,希望对大家有所帮助。
