Python學習手冊之Python異常和文件
在上一篇文章中,我們介紹了 Python 的函數和模塊,現在我們介紹 Python 中的異常和文件。
查看上一篇文章請點擊:https://www.cnblogs.com/dustman/p/9963920.html
異常和文件
異常
異常也叫例外。在之前的幾篇文章中,你已經看到過異常。當程序運行錯誤是出現,比如不正確的調用和代碼不規範等。當你的程序出現意外情況是就會發生異常並終止運行。
下面代碼用 5 除以 0 產生 ZeroDivisionError 異常。
num1 = 5
num2 = 0
print(num1/num2)
運行結果:
>>>
ZeroDivisionError: division by zero
>>>
不同的原因產生不同的異常,一般有:
ImportError:引入模塊錯誤,通常是模塊不存在。
IndexError:讀取列表超出索引範圍。
NameError:使用未聲明的變量。
SyntaxError:代碼語法錯誤。
TypeError:當操作或函數處理不合適類型。
ValueError:內建操作或函數,接收到類型正確,但值不正確。
Python 還有其他幾個內置的異常,比如 ZeroDivisionError 和 OSError。第三方庫也經常定義自己的異常。
異常處理
我們使用 try/except 語句捕捉程序運行時產生的異常。
try 塊用來包含可能產生異常的代碼塊。如果產生異常 try
try:
num1 = 5
num2 = 0
print(num1/num2)
print("Done!")
except ZeroDivisionError:
print("Has a error")
print("due to zero division")
運行結果:
>>>
Has a error
due to zero division
>>>
上面的例子裏 except 語句定義了 ZeroDivisionError 異常捕捉。
try 語句可以擁有多個 except 定義語句來處理異常。多個異常也可以使用一個 except 塊來捕捉。
try:
var = 5
print(var + "string!")
print(var/2)
except ZeroDivisionError:
print("Divided by zero!")
except (ValueError,TypeError):
print("Has a error!")
運行結果:
>>>
Has a error!
>>>
except 語句如果沒有申明要鋪獲的異常,將捕獲所有的異常。我們應該謹慎地使用這種異常處理方式,它雖然捕獲了意外錯誤但是卻把編程錯誤隱藏了。
try:
var = 5
print(var + "string!")
print(var/2)
except:
print("An error occurred")
運行結果:
>>>
An error occurred
>>>
這種異常處理方式通常用在處理用戶輸入。
finally 語句
假設你正在讀取一份文件。你應該確保文件對象被正確關閉,無論是否會發生異常。
為了確保代碼最終能夠運行不論是否有異常發生,我們可以使用 finally 語句。finally 放在 try/except 語句的後面。
try:
str = "Hello"
var = 5
print(str)
print(var/0)
except ZeroDivisionError:
print("Divided by zero")
finally:
print("This code will run no matter what")
運行結果:
>>>
Hello
Divided by zero
This code will run no matter what
>>>
下面代碼會輸出什麽?
try:
print(1)
except:
print("a")
finally:
print("Hello")
運行結果:
>>>
1
Hello
>>>
finally 語句最終會被執行不管前面的異常到沒有捕捉到,包括在 except 語句裏產生的異常。
try:
print(1)
print(5/0)
except ZeroDivisionError:
print(Error_var)
finally:
print("This is executed last!")
運行結果:
>>>
1
This is executed last!
ZeroDivisionError: division by zero
During handling of the above exception, another exception occurred:
NameError: name ‘Error_var‘ is not defined
>>>
拋出異常
使用 raise 語句拋出一個異常
print(1)
raise ZeroDivisionError
print(5)
運行結果:
>>>
1
ZeroDivisionError
>>>
你需要聲明你要拋出的例外名稱。
拋出的異常可以用參數來指出這是什麽錯誤。
age = 12
raise TypeError("Invalid type!")
運行結果:
>>>
TypeError("Invalid type!")
>>>
在 except 塊裏,raise 語句可以不用聲明異常的名稱重新拋出捕捉到的異常。
try:
num= 5/0
except:
print("Has a error")
raise
運行結果:
>>>
ZeroDivisionError: division by zero
Has a error
>>>
斷言
Python 的斷言就是檢測一個條件。如果條件為真,它什麽都不做,條件為假會觸發一個錯誤信息。
斷言可以打開或關閉。斷言使用 assert 語句聲明。
print(1)
assert 1 + 2 == 3
print("Yes")
assert 1 + 1 == 0
print("Yes")
運行結果:
>>>
1
Yes
AssertionError
>>>
程序員通常在函數的開頭放置斷言以檢查有效的輸入,在函數調用之後放置斷言以檢查有效的輸出。
斷言可以在運行是通過添加 -O 或 -OO 選項來關閉。
下面代碼打印出來什麽?
print(1)
assert 1 != 2
print(2)
assert True
print(3)
assert False
print(4)
assert 1 + 1 == 2
print(5)
運行結果:
>>>
1
2
3
AssertionError
>>>
斷言的第二個參數可以用來給 AssertionError 做參數。
num = 5
assert (num <= 0),"The num is bigger than zero"
運行結果:
>>>
AssertionError: The num is bigger than zero
>>>
AssertionError 異常可以像任何其他異常一樣使用 try/except 語句被捕捉和處理,如果程序不處理,這種類型的異常將終止程序的運行。
文件處理
打開文件
讀寫文件是最常見的 IO(輸入輸出)操作。Python 內置了讀寫文件的函數,要讀寫文件需要打開一個文件對象,使用 open 函數。
open 函數打開的對象在 Python 中統稱為 file-like Object。除了文件外,還可以是內存的字節流,網絡流,自定義流等等。
f = open("test.txt")
註意:open 函數的參數是文件的路徑。如果文件與程序位於同一個目錄中,則可以不要指定路徑直接使用文件名。
可以使用 open 函數的第二個參數來指定打開文件的模式。
# read mode
open("test.txt", "r")
open("test.txt")
# write mode
open("test.txt", "w")
# binary write mode
open("test.txt", "wb")
打開文件模式列表:
特別註意:使用 "w" 模式時,如果文件已經存在,會把舊文件的內容全部都清除掉。
文件打開後應該使用 close 方法關閉文件。
f = open("test.txt","w")
# close the file
f.close()
接下來我們會讀取和寫入文件。
讀取文件
使用 open 方法打開的文件可以使用 read 方式來讀取內容。
f = open("test.txt","r")
content = f.read()
print(content)
f.close()
打印文件名為 "test.txt" 的所有內容。
若要讀取一定數量的文件內容,可以使用一個數字作為參數來調用 read 函數。該數字確定要讀取多少個字節的內容。
可以對同一個文件對象進行多次的 read 調用,該字節讀取文件內容。在沒有參數的情況下,read 函數返回文件的其余部分。
f = open("test.txt","r")
print(f.read(32))
print(f.read(16))
print(f.read(8))
print(f.read())
f.close()
當所有的內容被讀取後,再調用 read 函數返回空字符串。
f = open("test.txt","r")
f.read()
print("reading")
print(f.read())
print("finished!")
f.close()
運行結果:
>>>reading
finished!
>>>
打開一個文件讀取它的內容,打印內容的長度。
f = open("test.txt","r")
str = f.read()
print(len(str))
f.close()
運行結果:
>>>
16
>>>
要一行一行地讀取,我們可以使用 readline 方法,也使用 readlines 一次讀取所有內容並返回一個列表,列表裏的每一項元素表示一行內容。
f = open("test.txt","r")
print(f.readlines())
f.close()
運行結果:
>>>
[‘I like Python!!!‘]
>>>
使用 for 語句遍歷文件的每一行:
f = open("test.txt","r")
for line in f:
print(line)
f.close()
運行結果:
>>>
Line 1 : Hello world!
Line 2 : I like Python!
Line 3 : I like Java!
>>>
在輸出中,返回的行包含換行符,打印 print 函數在輸出的末尾自動添加新行。
寫文件
使用 write 方法把內容寫到文件裏。
f = open("test.txt","w")
f.write("I am happy!")
f.close()
f = open("test.txt","r")
print(f.read())
f.close()
運行結果:
>>>
I am happy!
>>>
如果文件不存在,"w" 將會創建一個文件。
寫入模式下,如果文件存在將清除全部內容並往文件寫入新內容。
f = open("test.txt","r")
print("Reading...")
print(f.read())
print("Finished!")
f.close()
f = open("test.txt","w")
f.write("New text")
f.close()
f = open("test.txt","r")
print("Reading new contents")
print(f.read())
print("Finished!")
f.close()
運行結果:
>>>
Reading...
I am happy!
Finished!
Reading new contents
New text
Finished!
>>>
特別註意:原有的文件將被新內容重寫。
如果 write 寫入成功,方法返回寫入的字節數。
msg = "I like Python!!!"
f = open("test.txt","w")
count = f.write(msg)
print(count)
f.close()
運行結果:
>>>
16
>>>
讀寫文件
確保文件在使用後始終關閉,避免浪費資源是良好的編程習慣。我們使用 try/finally 語句。
try:
f = open("test.txt")
print(f.read())
finally:
f.close()
當異常發生時也能確保文件對象被正確關閉。
每次都這樣要關閉文件是在太繁瑣。所以,Python 引入了 with 語句來幫我們自動調用 close() 方法。
with open("test.txt") as f:
print(f.read())
使用 with 語句打開文件是個好習慣,就算有例外發生,with 語句也會自動幫我們關閉文件句柄。
“朝著一個方向瘋狂奔跑的感覺,真好。”
Python學習手冊之Python異常和文件