1. 程式人生 > >Python基礎筆記_Day13_Python檔案讀寫IO、異常、自定義異常

Python基礎筆記_Day13_Python檔案讀寫IO、異常、自定義異常

Day13_Python檔案讀寫IO、異常、自定義異常

13.01_Python語言基礎(檔案概述)(熟練)
13.02_Python語言基礎(檔案開啟關閉)(掌握)
13.03_Python語言基礎(檔案的讀寫)(掌握)
13.04_Python語言基礎(製作檔案的備份)(掌握)
13.05_Python語言基礎(檔案的定位讀寫)(掌握)
13.06_Python語言基礎(檔案的操作)(掌握)
13.07_Python語言基礎(StringIO和BytesIO)(熟練)
13.08_Python語言基礎(異常概述)(掌握)
13.09_Python語言基礎(異常的處理)(掌握)
13.10_Python語言基礎(捕獲多個異常)(掌握)
13.11_Python語言基礎(else)(掌握)
13.12_Python語言基礎(try...finally)(掌握)
13.13_Python語言基礎(異常的傳遞)(掌握)

13.01_Python語言基礎(檔案概述)(熟練)

檔案概述:

  • 常見的檔案格式: txt avi html zip doc

檔案的作用

  • 檔案作用:把資料儲存起來

13.02_Python語言基礎(檔案開啟關閉)(掌握)

我們日常中操作檔案的過程:
開啟一個檔案 ,或者新建一個檔案
讀寫資料
關閉檔案

Python語言中檔案的開啟

在python中,使用open()函式可以開啟一個已經存在的檔案,或者建立一個新的檔案
格式:
   open(檔名,訪問模式)

f = open("test.txt","w")

訪問模式概述

訪問模式                  說明
w	開啟一個檔案只用於寫入,如果該檔案已經存在則將其覆蓋,如果不存在,建立新檔案
r   以只讀的方式開啟一個檔案,檔案的指標將會在檔案的開頭位置,預設模式,如果檔案不存在會報錯
a   開啟一個檔案用於追加,如果該檔案已經存在,檔案的指標會放在檔案的結尾,即新的內容將會寫入已有內容之後,如果檔案不存在,如果檔案不存在,建立以一個新檔案進行寫入

rb	以二進位制的方式開啟一個檔案用於只讀,檔案的指標將會在檔案的開頭位置,預設模式,如果檔案不存在會報錯
wb  以二進位制的格式開啟一個檔案只用於寫入,如果該檔案已經存在則將其覆蓋,如果不存在,建立新檔案
ab	以二進位制方式開啟一個檔案用於追加,如果該檔案已經存在,檔案的指標會放在檔案的結尾,即新的內容將會寫入已有內容之後,如果檔案不存在,如果檔案不存在,建立以一個新檔案進行寫入

r+	開啟一個檔案用於讀寫,檔案的指標放在檔案的開頭位置
w+	開啟一個檔案用於讀寫,如果該檔案已經存在將其覆蓋,如果檔案不存在,建立一個新檔案
a+	開啟一個檔案用於讀寫,檔案的指標放在檔案的末尾位置,,即新的內容將會寫入已有內容之後,如果檔案不存在,如果檔案不存在,建立以一個新檔案進行寫入

rb+	以二進位制的方式開啟一個檔案用於讀寫,檔案的指標放在檔案的開頭位置
wb+	以二進位制的方式開啟一個檔案用於讀寫,如果該檔案已經存在將其覆蓋,如果檔案不存在,建立一個新檔案
ab+	以二進位制的方式開啟一個檔案用於讀寫,檔案的指標放在檔案的末尾位置,,即新的內容將會寫入已有內容之後,如果檔案不存在,如果檔案不存在,建立以一個新檔案進行寫入

Python語言中檔案的關閉

使用函式:
close()
f = open("test.txt","w")
f.close()
"""

注意:
close()作用—》釋放記憶體


13.03_Python語言基礎(檔案的讀寫)(掌握)

寫資料(write)

使用write()函式可以完成對檔案寫入內容
格式:
   f.write(str)

f = open("test.txt","w")
f.write("hello world !")
f.close()

注意:
如果檔案不存在則建立,如果存在,則先清空,在寫入資料


讀取資料(read/readline/readlines)

1.讀取資料使用read()函式,可以從檔案中讀取資料,
格式:
read(num)
num :  表示要從檔案中讀取的資料的長度(單位位元組),
如果num沒有傳入,那麼表示讀取檔案的所有資料

"""
# f = open("test.txt")
# content = f.read()
# print(content)
# content1 = f.read(5)
# print(content1)
# f.close()

注意:
如果使用了多次,那麼後面讀取的資料是從
上一次讀取完資料後的位置開始


第二種方式:readlines

  • 使用readlines可以按照行的方式把整個的檔案中的內容進行一次性讀取,
  • 返回一個列表,其中每一行的資料作為一個元素

f = open("test.txt", "r+")
f.write("hello python \n hello python \n hello python \nhello python ")
content = f.readlines()
print(type(content))
print(content)
# 獲取列表中所有的內容
i = 1
for temp in content:
    print("%d:%s" % (i, temp))
    i += 1
f.close()
執行輸出結果:
<class 'list'>
['hello python \n', ' hello python \n', ' hello python \n', 'hello python ']
1:hello python 
2: hello python 
3: hello python 
4:hello python 

再來一個例子

readline:返回的資料是str
f = open("test.txt","r")
content = f.readline()
print(type(content))
content2 = f.readline()
content3 = f.readline()

print(content)
print(content2) 
print(content3)
f.close()

執行輸出結果:
******************************
<class 'str'>
hello python 

 hello python 

 hello python 

思考:有一個很大的檔案5G,思想怎樣讀取裡面的資料(readline/read(num))


讀取CSV檔案

# Comma-Separated Values,CSV,有時也稱為字元分隔值
# 匯入CSV模組  pdf   圖片
import csv
def readCsv(path):
    infoList = []
    with open(path,"r") as f:
        allFileInfo = csv.reader(f)
        # print(type(allFileInfo))
        for row in allFileInfo:
            infoList.append(row)
    return infoList
path = r"檔案路徑"
info = readCsv(path)
print(info)

寫入csv資料

import csv
def writeCsv(path,data):
    with open(path,"w") as f:
        writer = csv.writer(f)
        for rowDate in data:
              writer.writerow(rowDate)


path = r"檔案路徑"
writeCsv(path,[["1","2","3"],["4","5","6"],["7","8","9"]])

13.04_Python語言基礎(製作檔案的備份)(掌握)

  • 任務描述:
    • 輸入檔名字,然後程式自動完成對該檔案的備份操作:

分析:
   input()-->string
   open()
   判斷使用者輸入的檔案是否存在
         存在 
              1.開啟檔案
              2.讀取資料
              3.關閉檔案
         不存在----》錯誤提示
   
   
   完成備份:
      1.拿到剛才讀取到的資料
      2.建立一個新檔案,將剛才讀取到的資料寫到這個新檔案中
      3.關閉檔案

oldFileName = input("請輸入需要備份的檔案:")
#開啟需要備份的檔案
oldFile = open(oldFileName,"r")
#讀取需要備份檔案的內容
#判斷是否開啟
if oldFile:
    #提取檔案的字尾名
    fileFlagNum = oldFileName.rfind(".")
    if fileFlagNum > 0:
        fileFlag = oldFileName[fileFlagNum]

    #組織新檔案的名字
    newFilename = oldFileName[:fileFlagNum]+"[復件]"+fileFlag
    #建立一個新的檔案
    newFile = open(newFilename,"w")
    #將舊檔案中的資料,一行一行的方式進行復制到新檔案中
    for lineContent in oldFile.readlines():
        newFile.write(lineContent)

    #關閉檔案
    oldFile.close()
    newFile.close()

13.05_Python語言基礎(檔案的定位)(掌握)

  • 定位:
    • 通俗的講就是找到一個位置

獲取當前讀寫檔案的位置

"""
獲取當前讀寫檔案的位置
在讀取檔案的過程中,如果想知道當前的位置,
可以使用函式tell()來獲取,是游標開始的位置
"""
# 開啟一個檔案
f = open("test.txt", "r")
str = f.read(3)
print(str)
# 查詢當前游標的位置
position = f.tell()
print(position)
str = f.read(3)
position = f.tell()
print(position)
f.close()

定為到某一個位置

如果在讀寫檔案的過程中,需要從另外一個位置進行操作,可以使用seek()函式
格式:
seek(offset,from)
offset:偏移量
from:方向
    0:表示檔案的開頭
    1:表示當前位置
    2:表示檔案的末尾
    
案例L:
把位置設定為:從檔案的開頭,偏移5個位元組
"""


#開啟一個檔案
f = open("test.txt","rb+")
str = f.read(30)
print(str)
#查詢游標當前的位置
# position = f.tell()
# print(position)
#重新設定位置
f.seek(-3,2)
position = f.tell()
print(position)
f.close()

注意:
如果開啟檔案的模式"r",而不是"rb",則會報錯
在文字檔案中,沒有使用b模式選項開啟檔案,只允許從檔案的開頭計算相對位置


13.06_Python語言基礎(檔案的操作)(掌握)

檔案重新命名

  • 概述:
    • 需要對檔案進行重新命名操作,刪除,python中有一個模組os模組----》檔案的操作
    • os模組中有 一個函式rename()可以完成對檔名的重新命名

格式和案例:
rename(需要修改的檔名,,新的檔名)
import os
# os.rename("test.txt","畢業論文.txt")

檔案的刪除

概述:
os模組中remove()可以完成對檔案的刪除操作   
格式:
remove(待刪除的檔名)
案例:
os.remove("畢業論文.txt")

建立一個資料夾

概述:
    使用os模組中mkdir()函式
    
 格式:
 mkdir(str)


案例:
import os
os.mkdir("張三")

獲取當前的目錄

概述:
   使用os模組中listdir()函式   
格式:
  listdir()
案例:
import os
print(os.listdir("./"))
#結果為當前目錄的檔案

刪除資料夾

概述:
   使用os模組中的rmdir()函式
 格式:
     rmdir(str)  
     str--->表示需要刪除的資料夾名稱
案例:
import os
os.rmdir("張三")

應用----批量修改檔名(重新命名)

13.07_Python語言基礎(StringIO和BytesIO)(熟練)

StringIO

  • 很多時候,資料讀寫不一定是檔案,也可能在記憶體中讀寫
  • StringIO:在記憶體中讀寫str

StringIO案例:

"""
StringIO
"""
from io import StringIO
f = StringIO()
f1 = f.write("hello")#返回的是寫入資料的位元組數(每次寫入的資料)
print(type(f1))
print(f1)#5
f2 = f.write(" ")
print(f2)#1
f3 = f.write("world!")
print(f3)#6
print(f)
print(f.getvalue())

"""
讀取StringIO檔案,可以用一個str初始化StringIO,
"""
f = StringIO("hello\nhi\ngoodbye!")
while True:
    s = f.readline()
    if s == "":
        break
    print(s.strip())

BytesIO

StringIO操作---》str
如果操作二進位制資料,需要使用BytesIO
BytesIO實現在記憶體中讀取byte資料

13.08_Python語言基礎(異常概述)(掌握)

異常的介紹

print("------test-----1")
open("123.txt","r")
print("-----test------2")

當python檢測到一個錯誤時,直譯器就無法繼續執行,反而出現錯誤提示—>異常


13.09_Python語言基礎(異常的處理)(掌握)

  • 當出現異常的時候如何處理?
    • 捕獲異常
  • 基本的格式:
    “”"
    try:
    可能報錯的程式碼

    except Exception as e:
    出錯之後的操作

    else:
    不出錯會執行
    finally:
    不論報錯與否都會執行
    “”"
  • 示例程式碼

import os

print("核心程式碼")

try:
    os.rename("file", "file00")
    # print("lalala")
    print("hello"[10])
except (Exception, IndexError) as e:
    print(e)
else:
    print("沒有報錯")
finally:
    print("關閉電源,放掉那個人")

print("比核心程式碼還重要的程式碼")
  • 程式看不到任何錯誤,因為用來except,
  • 捕獲到FileNotFoundError異常,並添加了處理方法

總結:
把可能出現問題的程式碼,放在try裡面,
把異常處理的程式碼放在except中


  • 思考:
    • 如果出現多個異常該如何處理?

try:
    print("------test-----1")
    open("123.txt","r")
except (IOError,NameError):
    print("找不到該檔案")
print("-----test------2")
print("-----test   3")
"""
報錯,異常處理的型別不正確
"""

13.10_Python語言基礎(捕獲多個異常)(掌握)

獲取異常的資訊

try:
    open("123.txt","r")
    print("hello[10]")
except (FileNotFoundError, IndexError) as e:
    # print("檔案不存在....")
    print(e)

關鍵字as e後面跟的是錯誤的描述資訊errorMsg
那麼它的基本格式:
    except (錯誤型別) as 變數名:
        return 變數名
 如果同時存在多個異常,把異常寫成元組放在except後面

捕獲所有的異常

# exception
try:
    # open("133.txt","r")
    # print(AA.aa())
    print(abcd)
    open("134.txt", "r")
    print(AB.aa())
    print(abcdaaa)
except Exception as reslut:
    print(reslut)

13.11_Python語言基礎(else)(掌握)

  • 概述:
    • 如果沒有捕獲到異常,那麼執行else中的程式碼

try:
    num = 300
    print(num)

except NameError as errormsg:
    print(errormsg)
else:
    print("沒有捕獲到異常,真高興!")

13.12_Python語言基礎(try…finally)(掌握)

  • try…finally:
    • 在程式中,如果一段程式碼必須要執行,無論異常是否產生都要去執行,那麼此時需要使用finally
    • 如:檔案的關閉,釋放鎖,把資料連線返回連線池

13.13_Python語言基礎(異常的傳遞)(掌握)

  • 異常的傳遞
    • 我們呼叫方法的時候,方法中可能出現錯誤,
    • 這個錯誤或傳遞到當前執行的主d程式碼中,需要做異常的處理
    • 可以再被呼叫的方法中處理,也可以在主程式碼中處理

import os

def demo13():
    try:
        os.remove("file")
    except Exception as e:
        print(e)

def get_result(*args):
    result = 0
    for i in args:
        result += i
    return result

while True:
    select = int(input("請輸入您的選擇"))
    if select == 1:
		# 可以再此處處理異常,也可以在被呼叫的函式中處理異常
        # try:
        #     demo13()
        # except Exception as e:
        #     print(e)
        demo13()
    elif select == 2:
        print(get_result(1, 2, 3, 4, 5))
    elif select == 3:
        break
    else:
        print("輸入有誤")

13.14_Python語言基礎(try巢狀)(掌握)

  • 以前程式碼中經常遇到的異常
    • IndexError
    • ValueError
    • ZeroDivisionError
    • FileNotFoundError
  • 異常的巢狀
    • 如果出現異常,那麼這個異常子級的程式碼講無法繼續執行
    • 和他平行的那一級可以正常執行

print("程式碼開始執行")
try:
    print("異常處理的第一層")
    try:
        print(1 / (int(input("請輸入一個整數:"))))
        try:
            print(input("請輸入一個很長的字串")[10])
        except Exception as e:
            print(e)
        try:
            print("我是很長字串下面那句")
        except Exception as e:
            print(e)
    except Exception as e:
        print(e)
except Exception as e:
    print(e)
print("程式碼執行結束")

13.15_Python語言基礎(丟擲自定義異常)(掌握)

  • 如何定義一個自定義的異常
    • 需要使用raise語句用來引發異常
    • 異常和錯誤物件必須有一個名字,並且是error或者是exception的子類
  • raise語句的基本的格式
  • raise 自定義的異常類的物件

#自定義的異常類,判斷密碼長度,如果長度小於6就報錯
class ShortInputException(Exception):
    def __init__(self, length):
        self.length = length
        self.atLeast = 6

    def __str__(self):
        return "ShortInputException: 最小長度要求是6,,您輸入的是%d" % self.length


try:
    password = input("請輸入密碼:")
    if len(password) < 6:
        # raise 丟擲異常
        raise ShortInputException(len(password))
except ShortInputException as e:
    print(e)
else:
    print("密碼長度合法")