
作者|Chad Hansen
來(lái)源|Python學(xué)習(xí)開(kāi)發(fā)
英文|Understanding the Python Traceback – Real Python
在寫(xiě) Python 代碼的時(shí)候,當(dāng)代碼中出現(xiàn)錯(cuò)誤,會(huì)在輸出的時(shí)候打印 Traceback 錯(cuò)誤信息,很多初學(xué)者看到那一堆錯(cuò)誤信息,往往都會(huì)處于懵逼狀態(tài),腦中總會(huì)冒出一句,這都是些啥玩意。如果你是第一次看到它,也許你不知道它在告訴你什么。雖然 Python 的 Traceback 提示信息看著挺復(fù)雜,但是里面豐富的信息,可以幫助你診斷和修復(fù)代碼中引發(fā)異常的原因,以及定位到具體哪個(gè)文件的哪行代碼出現(xiàn)的錯(cuò)誤,所以說(shuō)學(xué)會(huì)看懂 Traceback 信息是非常重要的,另外在面試的時(shí)候也經(jīng)常會(huì)問(wèn)到 Python 中的異常類(lèi)型及其含義,那么,接下來(lái)就讓我們對(duì)其進(jìn)行詳細(xì)理解。
什么是 Traceback
Traceback 是 Python 錯(cuò)誤信息的報(bào)告。在其他編程語(yǔ)言中有著不同的叫法包括 stack trace, stack traceback, backtrac 等名稱, 在 Python 中,我們使用的術(shù)語(yǔ)是 Traceback。后面我提到的錯(cuò)誤信息等詞都表示Traceback。
當(dāng)你的程序?qū)е庐惓r(shí),Python 將打印 Traceback 以幫助你知道哪里出錯(cuò)了。下面是一個(gè)例子來(lái)說(shuō)明這種情況
# example.py def greet(someone ): print('Hello, ' + someon ) greet('Chad')
這里首先定義了函數(shù) greet,然后傳入?yún)?shù) someone,然后函數(shù)內(nèi),一個(gè) print 語(yǔ)句其中 someon 是一個(gè)沒(méi)有定義的變量,
然后通過(guò) greet ('Chad'),調(diào)用剛才定義的 greet 函數(shù),運(yùn)行之后會(huì)出現(xiàn)如下錯(cuò)誤信息。
(Python 中的錯(cuò)誤信息開(kāi)頭就是 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
此錯(cuò)誤輸出包含診斷問(wèn)題所需的所有信息。錯(cuò)誤輸出的最后一行一般會(huì)告訴你引發(fā)了什么類(lèi)型的異常,以及關(guān)于該異常的一些相關(guān)信息。錯(cuò)誤信息的前幾行指出了引發(fā)異常的代碼文件以及行數(shù)。
在上面的錯(cuò)誤信息中,異常類(lèi)型是 NameError,意思是名稱使用了一個(gè)沒(méi)定義的名稱(變量、函數(shù)、類(lèi))的引用。在本例中,引用的名稱是 someon。
一般情況下看錯(cuò)誤信息的最后一行就能定位到錯(cuò)誤的原因。然后在代碼中搜索錯(cuò)誤提示中的名稱"someon",然后發(fā)現(xiàn)這是一個(gè)拼寫(xiě)錯(cuò)誤,然后我們改成 someone 即可。
然而,有些代碼的錯(cuò)誤信息要比這個(gè)復(fù)雜的多。
如何閱讀 Python 的 Traceback 信息?
當(dāng)你想確定代碼為什么引發(fā)異常的時(shí)侯,可以根據(jù) Python 的 Traceback 獲取許多有用的信息。下面,將列舉一些常見(jiàn)的 Traceback,以便理解 Tracebac 中包含的不同信息。
Python Traceback 信息一覽
每個(gè) Python 的 Traceback 信息都有幾個(gè)重要的部分。下圖顯示了各個(gè)組成部分:
一個(gè)具體的
通過(guò)一些特定的 Traceback 信息,可以幫助我們更好地理解并查看 Traceback 將提供什么信息。
通過(guò)下面的示例代碼來(lái)說(shuō)明 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 )
定義一個(gè) who_to_greet 函數(shù),然后接受一個(gè)值 person,并根據(jù) if 判斷返回相應(yīng)結(jié)果。
然后,greet 函數(shù)接受一個(gè) someone 和一個(gè)可選的 greeting,之后調(diào)用 print 函數(shù),在 print 中調(diào)用 who_to_greet 函數(shù)并傳入?yún)?shù) someone。
最后,greet_many(),將迭代 people 列表并調(diào)用 greet 函數(shù)。如果通過(guò)調(diào)用 greet()引發(fā)異常,則會(huì)打印一個(gè)簡(jiǎn)單的問(wèn)候語(yǔ)。
只要提供了正確的輸入,此代碼就沒(méi)有任何可能導(dǎo)致異常被引發(fā)的錯(cuò)誤。
如果你在 greetings.py 中調(diào)用 greet 函數(shù),并傳入值(例如 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'
之前我們說(shuō)過(guò)閱讀 Python 的 Traceback 信息,是由下而上進(jìn)行閱讀的,這里我們?cè)僖黄鹂匆豢础?/span>
首先,我們需要看的是錯(cuò)誤信息的最后一行,通過(guò)最后一行可以知道錯(cuò)誤的類(lèi)型以及一些錯(cuò)誤原因。
意思是說(shuō):調(diào)用 greet()的時(shí)候使用了一個(gè)未知的參數(shù),這個(gè)未知參數(shù)就是 greting。
好的,然后我們需要繼續(xù)向上看,可以看到導(dǎo)致異常的行。在這個(gè)例子中我們看到的是調(diào)用 greet 方法的具體代碼。
它的上一行提供了代碼所在文件的路徑,以及代碼文件的行號(hào)以及它所在的模塊。(Pycharm 中通過(guò)點(diǎn)擊文件鏈接可以定位到具體位置)
在這個(gè)例子中,因?yàn)槲覀兊拇a沒(méi)有使用任何其他 Python 模塊,所以我們?cè)谶@里看到<module>,它表示所處位置是在執(zhí)行的文件。
使用不同的文件和不同的調(diào)用方式調(diào)用 greet 方法,得到的 Traceback 信息也是不同的,下面就通過(guò)文件導(dǎo)入的形式來(lái)執(zhí)行 greet 方法??纯唇Y(jié)果有什么區(qū)別吧
# example.py from greetings import greet greet (1)
運(yùn)行之后的結(jié)果
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
在本例中引發(fā)的異常同樣是一個(gè)類(lèi)型錯(cuò)誤,但這一次消息的幫助要小一些。它只是告訴你,在代碼的某個(gè)地方,字符串只能和字符串拼接,不能是 int。
向上移動(dòng),可以看到執(zhí)行的代碼行。然后是文件和行號(hào)的代碼。不過(guò),這一次我們得到的不是,而是正在執(zhí)行的函數(shù)的名稱 greet()。
然后繼續(xù)往上看,一行執(zhí)行的代碼,我們看到問(wèn)題代碼是 greet()函數(shù)調(diào)用時(shí)傳入了一個(gè)整數(shù)。
有時(shí)在引發(fā)異常之后,另一部分代碼會(huì)捕獲該異常并導(dǎo)致異常。在這種情況下,Python 將按接收順序輸出所有異常信息,最外層的異常信息處于 Traceback 內(nèi)容的最下面位置。
可能看起來(lái)有點(diǎn)懵,下面使用一個(gè)具體例子進(jìn)行說(shuō)明。
在 greetings.py 文件中調(diào)用 greet_many 方式具體調(diào)用代碼如下:
greet_many (['Chad', 'Dan', 1])
運(yùn)行之后輸出的錯(cuò)誤信息如下
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,這次好像不太一樣,比之前的內(nèi)容多了不少,而且有兩個(gè) Traceback 塊信息,這是什么意思呢?
注意這句話
During handling of the above exception, another exception occurred:
它的意思是:在處理上述異常期間,發(fā)生了另一個(gè)異常。簡(jiǎn)單理解就是在 except 中的代碼出現(xiàn)了異常。所以導(dǎo)致了這種現(xiàn)象。
這個(gè)例子就是在第三次循環(huán)的時(shí)候 person=1 然后字符串 hi 和1 不能進(jìn)行拼接操作,然后再次引發(fā)了異常。
查看所有的錯(cuò)誤信息輸出可以幫助您了解異常的真正原因。
有時(shí),當(dāng)您看到最后一個(gè)異常被引發(fā),并由此產(chǎn)生錯(cuò)誤信息時(shí),
你可能仍然看不出哪里出錯(cuò)了。比如這例子,直接通過(guò)最后的異??床坏絾?wèn)題具體出在哪,這個(gè)時(shí)候就要考慮繼續(xù)往上看了。
Python 中有哪些常見(jiàn)的異常類(lèi)型
在編程時(shí),知道如何在程序引發(fā)異常時(shí)讀取 Python 異常信息非常有用,如果再了解一些常見(jiàn)的異常類(lèi)型那就更好了。
有時(shí)候在面試的時(shí)候也會(huì)遇到提問(wèn) Python 中常見(jiàn)的異常類(lèi)型,以及其含義,所以這里也建議大家都了解以下。
下面就列舉一些出現(xiàn)頻次高而且非常重要的異常類(lèi)型,希望大家能夠有一定的印象。
AttributeError
當(dāng)你訪問(wèn)一個(gè)對(duì)象的屬性,但是這個(gè)屬性并沒(méi)有在這個(gè)對(duì)象定義的時(shí)候,就會(huì)引發(fā) AttributeError。
下面是一個(gè)引發(fā) AttributeError 異常的示例:
a = 1 a.b
運(yùn)行之后引發(fā)異常
Traceback (most recent call last ): File "/Users/chenxiangan/pythonproject/demo/exmpale.py", line 2, in <module> a.b AttributeError: 'int' object has no attribute 'b'
AttributeError 的錯(cuò)誤消息行告訴我們特定對(duì)象類(lèi)型(在本例中為 int)沒(méi)有訪問(wèn)的屬性,
在這個(gè)例子中屬性為 b。點(diǎn)擊文件鏈接可以快速定位到具體的錯(cuò)誤代碼的位置。
大多數(shù)情況下,引發(fā)這個(gè)異常表明你正在處理的對(duì)象可能不是你期望的類(lèi)型。
a_list = (1, 2) a_list.append (3)
運(yùn)行之后拋出異常信息
Traceback (most recent call last ): File "/Users/chenxiangan/pythonproject/demo/exmpale.py", line 2, in <module> a_list.append (3) AttributeError: 'tuple' object has no attribute 'append'
這里嘗試給 a_list 對(duì)象進(jìn)行 append 操作但是引發(fā)了異常,
這里的錯(cuò)誤信息說(shuō),tuple 對(duì)象沒(méi)有 append 屬性。
原因就是以為 a_list 是列表但是實(shí)際上它是元組,
元組是不可變類(lèi)型不支持添加元素操作所以出錯(cuò)了。這里也告訴大家,以后定義變量名的時(shí)候也要主要規(guī)范問(wèn)題,否則就容易出現(xiàn)這種,期望類(lèi)型錯(cuò)誤的情況。
還有一種情況就是當(dāng)對(duì) None 進(jìn)行屬性操作的時(shí)候,很容易引發(fā)上面的異常
a_list = None a_list.append (3)
運(yùn)行拋出異常
Traceback (most recent call last ): File "/Users/chenxiangan/pythonproject/demo/exmpale.py", line 2, in <module> a_list.append (3) AttributeError: 'NoneType' object has no attribute 'append'
是不是很眼熟啊,遇到這種情況不要慌,分析看看你的哪個(gè)對(duì)象是 None 就好了。
ImportError
在使用 import 導(dǎo)入模塊時(shí),如果要導(dǎo)入的模塊找不到,或者從模塊中導(dǎo)入模塊中不存在的內(nèi)容。這時(shí)就會(huì)觸發(fā) ImportError 類(lèi)型的錯(cuò)誤或者它的子類(lèi) ModuleNotFoundError。
import aaa
運(yùn)行后輸出
Traceback (most recent call last ): File "/Users/chenxiangan/pythonproject/demo/exmpale.py", line 1, in <module> import aaa ModuleNotFoundError: No module named 'aaa'
在這個(gè)例子中可以看到,當(dāng)我們使用 import 導(dǎo)入一個(gè)不存在的模塊時(shí),就會(huì)出現(xiàn) ModuleNotFoundError 的錯(cuò)誤,Traceback 最下面一句信息給出了原因,
沒(méi)有名為 aaa 的模塊.
然后我們?cè)龠\(yùn)行一個(gè)例子
from collections import asdf
運(yùn)行之后的內(nèi)容
Traceback (most recent call last ): File "/Users/chenxiangan/pythonproject/demo/exmpale.py", line 1, in <module> from collections import asdf ImportError: cannot import name 'asdf' from 'collections'
根據(jù)前面的經(jīng)驗(yàn)我們可以得知原因,不能從 collections 模塊中導(dǎo)入名為 asdf 的模塊。
有時(shí)候?yàn)榱顺绦蚰芗嫒菰诟鱾€(gè)系統(tǒng)的時(shí)候,如果一個(gè)包找不到,找另一個(gè)的時(shí)候,比如在 windows 中不能使用 ujson ,uvloop這兩個(gè)包,但是在 unix 系統(tǒng)上是可以運(yùn)行的,這個(gè)時(shí)候我們就可以使用下面的方法。
try: import ujson as json except ImportError as e: import json
首先導(dǎo)入 ujson 然后使用 as 給他重命名為 json,如果出現(xiàn)錯(cuò)誤就會(huì)進(jìn)入 except 模塊
然后導(dǎo)入標(biāo)準(zhǔn)庫(kù)的 json 包,因?yàn)檫@邊的庫(kù)名已經(jīng)叫 json 了所以不用再重命名了。記住這個(gè)技巧非常的有用哦。
IndexError
當(dāng)你嘗試從序列(如列表或元組)中檢索索引,但是序列中找不到該索引。此時(shí)就會(huì)引發(fā) IndexError。
例如
a_list = ['a', 'b'] a_list[3]
運(yùn)行之后的結(jié)果
Traceback (most recent call last ): File "/Users/chenxiangan/pythonproject/demo/exmpale.py", line 2, in <module> a_list[3] IndexError: list index out of range
通過(guò) IndexError 的錯(cuò)誤消息的最后一不能得到一個(gè)準(zhǔn)確的信息,只知道一個(gè)超出范圍的序列引用以及序列的類(lèi)型,在本例中是一個(gè)列表。我們需要往上閱讀錯(cuò)誤信息,才能確定錯(cuò)誤的具體位置。這里我們得知錯(cuò)誤代碼是 a_list[3]原因是索引3 超出了列表的范圍,因?yàn)樽畲缶褪?(索引下標(biāo)從0 開(kāi)始的)。
KeyError
與 IndexError 類(lèi)似,當(dāng)你訪問(wèn)映射(通常是 dict )中不包含的鍵時(shí),就會(huì)引發(fā) KeyError。
a_dict={} a_dict['b']
運(yùn)行之后
Traceback (most recent call last ): File "/Users/chenxiangan/pythonproject/demo/exmpale.py", line 2, in <module> a_dict['b'] KeyError: 'b'
KeyError 的錯(cuò)誤消息行給出找不到關(guān)鍵字 b。并沒(méi)有太多的內(nèi)容,但是,結(jié)合上面的錯(cuò)誤信息,就可以解決這個(gè)問(wèn)題。
NameError
當(dāng)你引用了變量、模塊、類(lèi)、函數(shù)或代碼中沒(méi)有定義的其他名稱時(shí),將引發(fā) NameError。
def greet (person ): print (f'Hello, {persn}') greet ('World')
運(yùn)行之后
Traceback (most recent call last ): File "/Users/chenxiangan/pythonproject/demo/exmpale.py", line 3, in <module> greet ('World') File "/Users/chenxiangan/pythonproject/demo/exmpale.py", line 2, in greet print (f'Hello, {persn}') NameError: name 'persn' is not defined
NameError traceback 的錯(cuò)誤消息行給出了缺失的名稱 persn。
這個(gè)例子中,在 print 使用了沒(méi)有定義過(guò)的變量 persn 所以出現(xiàn)了錯(cuò)誤。
一般在拼寫(xiě)變量名出現(xiàn)問(wèn)題時(shí)會(huì)引發(fā)這種錯(cuò)誤。
SyntaxError
當(dāng)代碼中有不正確的 Python 語(yǔ)法時(shí),就會(huì)引發(fā) SyntaxError。
下面的問(wèn)題是函數(shù)定義行末尾缺少一個(gè)冒號(hào)。
def greet (person )
運(yùn)行之后
File "/Users/chenxiangan/pythonproject/demo/exmpale.py", line 1 def greet (person ) ^ SyntaxError: invalid syntax
SyntaxError 的錯(cuò)誤消息行只告訴你代碼的語(yǔ)法有問(wèn)題。查看上面的行才能得到問(wèn)題所在的行,通常會(huì)用一個(gè)^(插入符號(hào))指向問(wèn)題點(diǎn)。
此外,細(xì)心的朋友會(huì)注意到,在 SyntaxError 異常內(nèi)容的第一行沒(méi)有了之前的(most recent call last )。
這是因?yàn)?SyntaxError 是在 Python 嘗試解析代碼時(shí)引發(fā)的,實(shí)際上代碼并沒(méi)有執(zhí)行。
TypeError
當(dāng)你的代碼試圖對(duì)一個(gè)無(wú)法執(zhí)行此操作的對(duì)象執(zhí)行某些操作時(shí),例如將字符串添加到整數(shù)中,以及一開(kāi)始的例子使用 append 方法給元組添加元素,這些都會(huì)引發(fā) TypeError。
以下是引發(fā) TypeError 的幾個(gè)示例:
>>> 1 + '1' Traceback (most recent call last ): File "<stdin>", line 1, in <module> TypeError: unsupported operand type (s ) for +: 'int' and 'str' >>> '1' + 1 Traceback (most recent call last ): File "<stdin>", line 1, in <module> TypeError: must be str, not int >>> len (1) Traceback (most recent call last ): File "<stdin>", line 1, in <module> TypeError: object of type 'int' has no len ()
以上所有引發(fā)類(lèi)型錯(cuò)誤的示例都會(huì)產(chǎn)生包含不同消息的錯(cuò)誤消息行。它們每一個(gè)都能很好地告訴你哪里出了問(wèn)題。
前兩個(gè)示例嘗試將字符串和整數(shù)相加。然而,它們有細(xì)微的不同
錯(cuò)誤消息行反映了這些差異。
最后一個(gè)示例嘗試在 int 上調(diào)用 len ()。
錯(cuò)誤消息行告訴我們不能使用 int 執(zhí)行此操作。
ValueError
當(dāng)對(duì)象的值不正確時(shí)就會(huì)引發(fā) ValueError。這個(gè)和我們前面說(shuō)的因?yàn)樗饕闹挡辉谛蛄械姆秶鷥?nèi),而導(dǎo)致 IndexError 異常類(lèi)似。
下面看兩個(gè)例子
>>> a, b, c = [1, 2] Traceback (most recent call last ): File "<stdin>", line 1, in <module> ValueError: not enough values to unpack (expected 3, got 2) >>> a, b = [1, 2, 3] Traceback (most recent call last ): File "<stdin>", line 1, in <module> ValueError: too many values to unpack (expected 2)
這些示例中的 ValueError 錯(cuò)誤消息行可以準(zhǔn)確地告訴我們值的一些問(wèn)題:
在第一個(gè)示例中,錯(cuò)誤信息行是沒(méi)有足夠多的值去 unpack (解包)。括號(hào)理面詳細(xì)的寫(xiě)了你希望解包3個(gè)值但實(shí)際上只給了2 個(gè)。
第二個(gè)示例中,錯(cuò)誤信息行是解包太多的值。先解包3 個(gè)值但是只給了2 個(gè)變量,所以括號(hào)里提示 expected 2 就是說(shuō)期望的實(shí)際是解包2 個(gè)值。
上面這些錯(cuò)誤類(lèi)型,基本上都是基礎(chǔ)遇到的,希望大家能熟悉記憶。
如何記錄這些錯(cuò)誤信息呢?
前面我們說(shuō)了很多異常的相關(guān)知識(shí),但是我們應(yīng)該如何利用好呢,這里我們就重點(diǎn)說(shuō)一下,如何通過(guò)記錄異常信息,方便后期程序的調(diào)試。
下面讓我們看一個(gè)關(guān)于使用 requests 模塊的例子。
首先需要導(dǎo)入 requests 包,使用 pip 即可。
import requests url = "http://wwww.baidu.com" response = requests.get (url ) print (response.status_code, response.text )
這是一個(gè)訪問(wèn)百度的例子,運(yùn)行之后,我們成功獲取了他的狀態(tài)碼和網(wǎng)頁(yè)源碼。
接下來(lái)我們對(duì) url 進(jìn)行修改然后再運(yùn)行。
import requests url = "http://urlis 233.com" response = requests.get (url ) print (response.status_code, response.text )
運(yùn)行之后我們發(fā)現(xiàn)程序出現(xiàn)了錯(cuò)誤,下面分析下這些錯(cuò)誤信息
省略前面部分 During handling of the above exception, another exception occurred: Traceback (most recent call last ): File "/Users/chenxiangan/pythonproject/demo/exmpale.py", line 3, in <module> response = requests.get (url ) File "/Users/chenxiangan/pythonproject/demo/venv/lib/python 3.7/site-packages/requests/api.py", line 75, in get return request ('get', url, params=params, **kwargs ) File "/Users/chenxiangan/pythonproject/demo/venv/lib/python 3.7/site-packages/requests/api.py", line 60, in request return session.request (method=method, url=url, **kwargs ) File "/Users/chenxiangan/pythonproject/demo/venv/lib/python 3.7/site-packages/requests/sessions.py", line 533, in request resp = self.send (prep, **send_kwargs ) File "/Users/chenxiangan/pythonproject/demo/venv/lib/python 3.7/site-packages/requests/sessions.py", line 646, in send r = adapter.send (request, **kwargs ) File "/Users/chenxiangan/pythonproject/demo/venv/lib/python 3.7/site-packages/requests/adapters.py", line 516, in send raise ConnectionError (e, request=request ) requests.exceptions.ConnectionError: HTTPConnectionPool (host='urlis 233.com', port=80): Max retries exceeded with url: / (Caused by NewConnectionError ('<urllib 3.connection.HTTPConnection object at 0x 10faeba 90>: Failed to establish a new connection: [Errno 8] nodename nor servname provided, or not known'))
這個(gè)錯(cuò)誤信息很長(zhǎng),它引發(fā)了許多其他的異常,最終的異常類(lèi)型是 requests.exceptions.ConnectionError。
往前面的錯(cuò)誤信息找可以發(fā)現(xiàn)問(wèn)題代碼,
File "/Users/chenxiangan/pythonproject/demo/exmpale.py", line 3, in <module> response = requests.get (url )
進(jìn)而定位到錯(cuò)誤,這個(gè)錯(cuò)誤原因主要是不存在地址"http://urlis 233.com",所以訪問(wèn)失敗。
錯(cuò)誤我們清楚了,但是一大堆的錯(cuò)誤信息搭載控制臺(tái)上,這樣看很不美觀,而且因?yàn)楫惓5脑蛭覀兊某绦蛑袛嗔?。這個(gè)時(shí)候我們就可以使用 Python 中的異常處理模塊 try/except 將代碼改成下面這樣
import requests url = "http://urlis 233.com" try: response = requests.get (url ) except requests.exceptions.ConnectionError: print ("-1","鏈接有問(wèn)題,訪問(wèn)失敗") else: print (response.status_code, response.text )
再次運(yùn)行可以得到下面的結(jié)果
-1 鏈接有問(wèn)題,訪問(wèn)失敗
ok,我們的程序可以正常運(yùn)行了,輸出的信息也美觀了。
但是,在大多數(shù)實(shí)際系統(tǒng)中,我們不希望只是打印捕獲的錯(cuò)誤信息到控制臺(tái)上,而是希望記錄這些信息,方便后面的錯(cuò)誤排查,所以最好的方案就是通過(guò)日志的方式記錄這些程序中的異常。
你可以通過(guò)導(dǎo)入 logging 模塊,記錄這些錯(cuò)誤,最終代碼如下
import logging import requests logger = logging.getLogger (__name__) url = "http://urlis 233.com" try: response = requests.get (url ) except requests.exceptions.ConnectionError as e: logger.exception () print (-1, '鏈接有問(wèn)題,訪問(wèn)失敗') else: print (response.status_code, response.content )
現(xiàn)在,當(dāng)你再運(yùn)行有問(wèn)題的 URL 的腳本時(shí),不僅會(huì)打印錯(cuò)誤,同時(shí)還會(huì)在日志文件中記錄這些錯(cuò)誤信息。
數(shù)據(jù)分析咨詢請(qǐng)掃描二維碼
若不方便掃碼,搜微信號(hào):CDAshujufenxi
SQL Server 中 CONVERT 函數(shù)的日期轉(zhuǎn)換:從基礎(chǔ)用法到實(shí)戰(zhàn)優(yōu)化 在 SQL Server 的數(shù)據(jù)處理中,日期格式轉(zhuǎn)換是高頻需求 —— 無(wú)論 ...
2025-09-18MySQL 大表拆分與關(guān)聯(lián)查詢效率:打破 “拆分必慢” 的認(rèn)知誤區(qū) 在 MySQL 數(shù)據(jù)庫(kù)管理中,“大表” 始終是性能優(yōu)化繞不開(kāi)的話題。 ...
2025-09-18CDA 數(shù)據(jù)分析師:表結(jié)構(gòu)數(shù)據(jù) “獲取 - 加工 - 使用” 全流程的賦能者 表結(jié)構(gòu)數(shù)據(jù)(如數(shù)據(jù)庫(kù)表、Excel 表、CSV 文件)是企業(yè)數(shù)字 ...
2025-09-18DSGE 模型中的 Et:理性預(yù)期算子的內(nèi)涵、作用與應(yīng)用解析 動(dòng)態(tài)隨機(jī)一般均衡(Dynamic Stochastic General Equilibrium, DSGE)模 ...
2025-09-17Python 提取 TIF 中地名的完整指南 一、先明確:TIF 中的地名有哪兩種存在形式? 在開(kāi)始提取前,需先判斷 TIF 文件的類(lèi)型 —— ...
2025-09-17CDA 數(shù)據(jù)分析師:解鎖表結(jié)構(gòu)數(shù)據(jù)特征價(jià)值的專(zhuān)業(yè)核心 表結(jié)構(gòu)數(shù)據(jù)(以 “行 - 列” 規(guī)范存儲(chǔ)的結(jié)構(gòu)化數(shù)據(jù),如數(shù)據(jù)庫(kù)表、Excel 表、 ...
2025-09-17Excel 導(dǎo)入數(shù)據(jù)含缺失值?詳解 dropna 函數(shù)的功能與實(shí)戰(zhàn)應(yīng)用 在用 Python(如 pandas 庫(kù))處理 Excel 數(shù)據(jù)時(shí),“缺失值” 是高頻 ...
2025-09-16深入解析卡方檢驗(yàn)與 t 檢驗(yàn):差異、適用場(chǎng)景與實(shí)踐應(yīng)用 在數(shù)據(jù)分析與統(tǒng)計(jì)學(xué)領(lǐng)域,假設(shè)檢驗(yàn)是驗(yàn)證研究假設(shè)、判斷數(shù)據(jù)差異是否 “ ...
2025-09-16CDA 數(shù)據(jù)分析師:掌控表格結(jié)構(gòu)數(shù)據(jù)全功能周期的專(zhuān)業(yè)操盤(pán)手 表格結(jié)構(gòu)數(shù)據(jù)(以 “行 - 列” 存儲(chǔ)的結(jié)構(gòu)化數(shù)據(jù),如 Excel 表、數(shù)據(jù) ...
2025-09-16MySQL 執(zhí)行計(jì)劃中 rows 數(shù)量的準(zhǔn)確性解析:原理、影響因素與優(yōu)化 在 MySQL SQL 調(diào)優(yōu)中,EXPLAIN執(zhí)行計(jì)劃是核心工具,而其中的row ...
2025-09-15解析 Python 中 Response 對(duì)象的 text 與 content:區(qū)別、場(chǎng)景與實(shí)踐指南 在 Python 進(jìn)行 HTTP 網(wǎng)絡(luò)請(qǐng)求開(kāi)發(fā)時(shí)(如使用requests ...
2025-09-15CDA 數(shù)據(jù)分析師:激活表格結(jié)構(gòu)數(shù)據(jù)價(jià)值的核心操盤(pán)手 表格結(jié)構(gòu)數(shù)據(jù)(如 Excel 表格、數(shù)據(jù)庫(kù)表)是企業(yè)最基礎(chǔ)、最核心的數(shù)據(jù)形態(tài) ...
2025-09-15Python HTTP 請(qǐng)求工具對(duì)比:urllib.request 與 requests 的核心差異與選擇指南 在 Python 處理 HTTP 請(qǐng)求(如接口調(diào)用、數(shù)據(jù)爬取 ...
2025-09-12解決 pd.read_csv 讀取長(zhǎng)浮點(diǎn)數(shù)據(jù)的科學(xué)計(jì)數(shù)法問(wèn)題 為幫助 Python 數(shù)據(jù)從業(yè)者解決pd.read_csv讀取長(zhǎng)浮點(diǎn)數(shù)據(jù)時(shí)的科學(xué)計(jì)數(shù)法問(wèn)題 ...
2025-09-12CDA 數(shù)據(jù)分析師:業(yè)務(wù)數(shù)據(jù)分析步驟的落地者與價(jià)值優(yōu)化者 業(yè)務(wù)數(shù)據(jù)分析是企業(yè)解決日常運(yùn)營(yíng)問(wèn)題、提升執(zhí)行效率的核心手段,其價(jià)值 ...
2025-09-12用 SQL 驗(yàn)證業(yè)務(wù)邏輯:從規(guī)則拆解到數(shù)據(jù)把關(guān)的實(shí)戰(zhàn)指南 在業(yè)務(wù)系統(tǒng)落地過(guò)程中,“業(yè)務(wù)邏輯” 是連接 “需求設(shè)計(jì)” 與 “用戶體驗(yàn) ...
2025-09-11塔吉特百貨孕婦營(yíng)銷(xiāo)案例:數(shù)據(jù)驅(qū)動(dòng)下的精準(zhǔn)零售革命與啟示 在零售行業(yè) “流量紅利見(jiàn)頂” 的當(dāng)下,精準(zhǔn)營(yíng)銷(xiāo)成為企業(yè)突圍的核心方 ...
2025-09-11CDA 數(shù)據(jù)分析師與戰(zhàn)略 / 業(yè)務(wù)數(shù)據(jù)分析:概念辨析與協(xié)同價(jià)值 在數(shù)據(jù)驅(qū)動(dòng)決策的體系中,“戰(zhàn)略數(shù)據(jù)分析”“業(yè)務(wù)數(shù)據(jù)分析” 是企業(yè) ...
2025-09-11Excel 數(shù)據(jù)聚類(lèi)分析:從操作實(shí)踐到業(yè)務(wù)價(jià)值挖掘 在數(shù)據(jù)分析場(chǎng)景中,聚類(lèi)分析作為 “無(wú)監(jiān)督分組” 的核心工具,能從雜亂數(shù)據(jù)中挖 ...
2025-09-10統(tǒng)計(jì)模型的核心目的:從數(shù)據(jù)解讀到?jīng)Q策支撐的價(jià)值導(dǎo)向 統(tǒng)計(jì)模型作為數(shù)據(jù)分析的核心工具,并非簡(jiǎn)單的 “公式堆砌”,而是圍繞特定 ...
2025-09-10