日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

Python基础(十)--文件相关

發布時間:2024/7/5 python 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python基础(十)--文件相关 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

?

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Python基礎(十)--文件相關

1 讀寫文件

1.1 獲取文件對象

1.2 文件讀取

1.3 文件寫入

1.4 文件定位

2 文件與路徑的操作

2.1 os模塊

2.2 os.path模塊

2.3 shutil模塊

2.4 glob模塊

3 序列化

3.1 csv

3.2 json

3.3 pickle

4 上下文管理器

4.1 自定義上下文管理器

4.2?@contextmanager裝飾器


? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Python基礎(十)--文件相關

1 讀寫文件

1.1 獲取文件對象

在操作系統中,一個text文檔,一張圖片,一首音樂,這些都是文件。文件會以其固有的格式保存在硬盤中。文件可以分為兩種類型:①文本文件:文本文件由若干可識別的字符組成,并且不能包含非文本字符之外的內容(圖片等),如,.txt,.bat都是文本文件,而.doc,.pdf則不是文本文件②二進制文件:由可識別的字符組成,如果我們用文本編輯器打開二進制文件,往往看到的都是一堆亂碼。

底層的角度來說,一切都是二進制格式的,文本文件,也是二進制文件的一種,只是其內容,是我們能夠識別的字符而已。

在Python中,可以通過open函數返回文件對象。文件對象是一個泛指,可以表示文件,也可以表示文件夾(路徑)。格式為:open(file, mode='r') file指定文件的路徑(相對路徑或絕對路徑),mode指定打開文件的模式,如下表。當讀入文件或者寫入文件時,會涉及到文件指針。文件指針指向的就是下一次要讀取或寫入的字符(或字節)位置,隨著讀取或寫入的進行,文件指針也會隨之而移動。

模式

說明

r(1)

讀模式(默認模式),用來讀取文件內容。文件指針在文件的開頭。文件需要事先存在,否則會產生異常。

w(1)

寫模式,用來向文件寫入數據。文件指針在文件的開頭。如果文件存在,則覆蓋文件,否則會創建文件。

a(1)

追加模式,用來向文件追加數據。文件指針在文件的末尾。如果文件存在,不會覆蓋文件(追加寫入),否則會創建文件。

x(1)

寫模式,用來向文件寫入數據。文件指針在文件的開頭。如果文件不存在,創建文件,否則產生錯誤。

t(2)

文本(字符串)模式(默認模式),以文本形式操作文件。

b(2)

二進制(字節)模式,以二進制形式操作文件。

U(3)

通用換行符模式(已不建議使用)。在該模式下,\n,\r\n或\r都會解析為換行符。不能與w、a、x或+模式同時使用(僅限于讀取文件時使用)。

+(3)

讀取或寫入。

上表的(1)(2)(3)模式中,不同組的模式可同時使用(除了與U不兼容的模式),例如rt,wb+等。同一組的模式同時使用,如rw,tb等。

當文件不再使用時,我們需要對文件進行關閉,從而斷開與外部文件的連接。斷開連接可以調用文件對象的close方法。

# open函數,參數1:文件路徑,參數2:操作文件的模式,返回文件對象 # 以r(讀取)模式操作文件時,文件必須存在,否則會產生FileNotFoundError fr = open("E:/test/test.txt","r") # 以w(寫入)或a(追加)模式操作文件時,文件不存在,不報錯而是創建文件 fw = open("E:/test/test1.txt","w") fa = open("E:/test/test2.txt","a") # 以x(寫入)模式操作文件時,文件必須存在,否則會產生FileNotFoundError fx = open("E:/test/test3.txt","w") # 訪問文件結束后,需要斷開與文件的連接,直接調用close并不好,可能在close方法前產生異常 # finally方式關閉文件 try:f = open("E:/test/test.txt", "r") finally:f.close() # with處打開文件,可以保證在with結束后一定能夠有效的關閉,無序顯示調用close方法 # with中可以使用as來保存文件對象(獲得文件兌現高的引用) with open("E:/test/test.txt") as f:pass

1.2 文件讀取

讀取文件的幾種方式如下:

方法描述
read(size=-1)讀取并返回文件內容。size指定讀取的大小。如果是文本模式,以字符為單位,如果是二進制模式,以字節為單位。如果size省略,或者為負數,則返回文件的全部內容。如果文件已經沒有內容可讀取,返回空串(""或b"")
readlline()返回文件的一行,保留末尾的換行符。如果沒有內容可以讀取,返回空串(""或b"")。
readllines()返回一個列表,列表中的每個元素為文件的一行內容,每行保留末尾的換行符。

文件對象也是迭代器:如果文件過大,這會占據大量的內容空間。此時readlines不是一個好的選擇。對于文件對象,其本身也是一個迭代器類型,我們可以使用for循環的方式對文件對象進行迭代,從而節省內存。

# 文件讀寫操作 with open("E:/test/test.txt","rt") as f:# t模式以字符(文本)形式操作文件,b模式以字節(二進制)形式操作文件# read讀取文件的數據,參數指定讀取的單位,如果參數缺失,或者為負值表示讀取所有# print(f.read(1))# print(f.read())pass # 如果使用了t模式,要求操作文件的編碼方式與目標文件的編碼方式一致 # 如果沒有顯示指定編碼方式,則使用平臺的編碼方式,可以使用encoding指定操作文件的編碼方式 with open("E:/test/test.txt","rt",encoding="UTF-8") as f:print(f.read())# 讀取文件的一行while True:line = f.readline()if line:print(line,end=" ")else:break# 返回一個列表,列表中的元素為每一行的內容,保留換行符# lines = f.readlines()# for line in lines:# print(line,end=" ") # 文件是迭代器類類型,每個元素就是文件的一行 from collections.abc import Iterator with open("E:/test/test.txt","rt",encoding="UTF-8") as f:print(isinstance(f,Iterator))for line in f:print(line,end="")

1.3 文件寫入

向文件寫入的幾種方式如下:

方法描述
write(content)將參數寫入到文件中,返回寫入的長度。如果是文本模式,以字符為單位,如果是二進制模式,以字節為單位
writelines(lines)參數lines為列表類型,將列表中所有元素寫入文件中
# 文件寫入 with open("E:/test/a.txt","wt") as f:f.write("寫入")# 向文件寫入列表f.writelines(["這是\n","列表\n"]) # b模式寫入 with open("E:/test/a.txt","wb") as f:f.write(b"abc") # 文件復制 with open("E:/test/b.txt","rb") as f1,open("E:/test/a.txt","rb") as f2:for line in f1:f2.write(line)

1.4 文件定位

通過文件對象的tell()和seek()方法可以獲取或設置文件指針的位置

tell():返回文件指針的位置,即下一個要讀取或寫入的字符(字節)位置。以字節為單位。

seek(offset, whence):?改變文件的指針。offset指定新的索引位置偏移量。whence指定偏移量的參照位置:0:從文件頭計算;1:從當前位置計算;2:從文件末尾計算

在文本模式下,如果whence的值不為0,則僅當offset的值為0時才是有效的。

# 文件定位 with open("E:/test/a.txt","rt",encoding="UTF-8") as f:# 返回當前文件指針的位置,以字節為單位print(f.tell())f.read(2)print(f.tell())# 改變文件指針的位置,參數1:偏移量,參數2:參照物# 在t模式下,如果第二個參數不為0,則只有第一個參數為0才支持,b模式無此限制f.seek(3,0)print(f.tell())

2 文件與路徑的操作

2.1 os模塊

os模塊提供了很多操作目錄與文件的功能,常用方法如下:

方法名描述
mkdir(path)創建path指定的目錄。如果path所在的父目錄不存在,或者path目錄已經存在,都會產生異常
makedirs(path,exist_ok=False)創建path指定的目錄。如果path所在的父目錄不存在,則會連同父目錄一同創建。如果path目錄已經存在,當exist_ok值為False,會產生異常,如果exist_ok值為True,則不會產生異常(默認值為False)
rmdir(path)刪除path指定的空目錄,但不會刪除父目錄。如果path目錄不存在,或者該目錄不為空,將會產生異常
removedirs(path)刪除path指定的空目錄。如果父目錄也為空,則會連同父目錄一同刪除(一直到根目錄為止)。如果path不存在,或者該目錄不為空,將會產生異常
remove(path)刪除path指定的文件。如果path不是一個文件,或者文件不存在,將會產生異常
getcwd()返回當前的工作目錄,即以腳本運行文件所在的目錄
chdir(path)改變當前的工作目錄,工作目錄由path指定
rename(src,dst)重命名一個文件或目錄。src指定源文件的路徑,dst指定重命名后的文件路徑。src與dest要求為同一目錄
renames(old,new)與rename相似,但是old與new指定的目錄可以不同(此時類似于移動文件)。在方法執行時,會刪除old路徑中左側所有的非空目錄,并根據需要,創建new路徑中不存在的目錄。在Windows系統,old與new必須在同一盤符中
listdir(path)獲取path指定目錄下所有的文件與子目錄名(包括隱藏文件),以列表形式返回。列表元素的順序是沒有任何保證的。如果path為空,則默認為當前目錄
system()在shell中執行command指定的命令
sep返回特定操作系統使用的分隔符
name返回操作系統的名稱。在Windows上返回nt,在Linux上返回posix
environ返回操作系統的環境變量
linesep返回操作系統使用的換行符
pathsep返回操作系統環境變量的分隔符
curdir返回當前目錄(.)
pardir返回上級目錄(..)

2.2 os.path模塊

os.path模塊提供了關于路徑操作的相關功能,常用方法如下:

方法名描述
abspath(path)返回path的絕對路徑
basename(path)返回path的最后一個部分。即path中操作系統分隔符(/或\等)最后一次出現位置后面的內容。如果path以操作系統分隔符結尾,則返回空字符串
commonpath(paths)參數paths為路徑的序列,返回最長的公共子路徑
dirname(path)返回path的目錄部分
exists(path)判斷路徑是否存在,存在返回True,否則返回False
getatime(path)返回文件或目錄的最后訪問時間
getmtime(path)返回文件或目錄的最后修改時間
getsize(path)返回文件的大小,以字節為單位
isabs(path)判斷path是否為絕對路徑,是返回True,否則返回False
isdir(path)判斷path是否為存在的目錄,是返回True,否則返回False
isfile(path)判斷path是否為存在的文件,是返回True,否則返回False
join(path,*paths)連接所有的path,以當前操作系統的分隔符分隔,并返回。空path(除了最后一個)將會丟棄。如果最后一個path為空,則以分隔符作為結尾。如果其中的一個path為絕對路徑,則絕對路徑之前的路徑都會丟棄,從絕對路徑處開始連接
split(path)將path分割成一個元組,元組含有兩個元素,第2個元素為path的最后一個部分,第一個元素為剩余之前的部分。(dirname與basename)

?

2.3 shutil模塊

shutil模塊提供了高級操作文件的方式。通過該模塊提供的功能,可以快捷方便的對文件或目錄執行復制,移動等操作。常用方法如下:

方法名描述
copy(src,dst)復制文件,返回復制后的文件路徑。src指定要復制的文件,如果dst是一個存在的目錄,則將文件復制到該目錄中,文件名與src指定的文件名一致,否則,將src復制到dst指定的路徑中,文件名為dst中指定的文件名
copy2(src,dst)與copy函數類似,但是copy函數不會保留文件的元信息,例如創建時間,最后修改時間等。copy2函數會盡可能保留文件的元信息
copytree(src,dst)復制一個目錄,目錄中的文件與子目錄也會遞歸實現復制,返回復制后的目錄路徑。src指定要復制的目錄,dst指定復制后的目標目錄,如果dst已經存在,則會產生異常
rmtree(path)刪除path指定的目錄,目錄中的子目錄與文件也會一并刪除
move(src,path)將文件或目錄移動到另外一個位置,src指定文件或目錄的路徑,當src為目錄時,會將該目錄下所有的文件與子目錄一同移動(遞歸)。dst指定移動的目標文件或目錄

使用copytree(src,dst)復制目錄時,可以結合ignore_patterns函數對目錄下的文件與子目錄進行排除。如:shutil.copytree("abc", "def", ignore=shutil.ignore_patterns("*.txt"))ignore參數指定忽略的文件或目錄,這樣,所有名稱以txt結尾的文件或目錄將不會復制到目標目錄中。

?

2.4 glob模塊

glob模塊提供列舉目錄下文件的方法,支持通配符*,?與[?]。常用方法如下:

glob(pathname,?*, recursive=False)

返回所有匹配pathname的文件與目錄名稱構成的列表,列表中元素的順序是沒有規律的。如果recursive值為True,則可以使用**匹配所有文件與目錄,包括所有子目錄中的文件與目錄(遞歸)。

pathname中可以指定通配符:①*:匹配任意0個或多個字符②?:匹配任意1個字符③[]:匹配[]內的任意一個字符,支持使用“-”區間的表示。例如[0-9]則匹配0到9任何一個字符,[a-f]則匹配a-f之間的任何一個字符

iglob(pathname, *, recursive=False)與glob功能相同,只是返回一個迭代器而不是列表。

?

3 序列化

3.1 csv

CSV(Comma Separated Values),是一種存文本格式的文件,文件中各個元素值通常使用逗號(,)進行分隔,但這不是必須的,擴展名為.csv。可以使用csv模塊來操作csv類型的文件。

# scv模塊 import csv # 寫入csv文件,在寫入的時候最好將newline設置為"",不然會產生空行 with open("E:/test/a.csv","wt",newline="") as f:# writer函數返回一個寫入器對象,能向參數指定的文件中寫入數據writer = csv.writer(f)writer.writerow(["張三","18","男"])writer.writerow(["李四","20","男"])# 一次寫入多行記錄的話提供一個二維列表,每個一維列表就是一條記錄writer.writerows([["王五","25","男"],["趙六","30","男"]]) # 讀取csv文件 with open("E:/test/a.csv","rt") as f:# reader函數返回一個讀取器對象(是可迭代對象),能夠讀取csv文件中的數據內容reader = csv.reader(f)for lines in reader:print(lines)

3.2 json

(1)什么是json

JSON(JavaScript Object Notation),是一種輕量級的數據交換格式。json采用的是一組鍵與值的映射,鍵與值之間使用“:”進行分隔,而鍵值對之間使用“,”進行分隔。json文件中的類型可以是:

類型描述
對象類型使用{}表示
數組類型使用[]表示
字符串類型使用雙引號表示
布爾類型true或false
數值類型整數與浮點數

格式如下:

{"desc": "json","data": {"content": ["content1", "content2", "content3"],"annotation": "注釋"} }

(2)dump與load處理程序,dumps與loads序列化與反序列化

可以通過json類型的數據進行對象的序列化與反序列化。

序列化:將對象類型轉換成字符串的形式。

反序列化:將序列化的字符串恢復為對象類型。

通過序列化與反序列化,我們就可以方便的對復雜的對象進行存儲與恢復(因為文件讀寫只支持字符串類型),或者通過網絡進行傳輸,將對象共享給遠程的其他程序使用。

# json文件提供不同項目之間的數據交換 import json data = {"desc": "json","data": {"content": ["content1", "content2", "content3"],"annotation": "注釋"} } with open("E:/test/a.json","wt") as f:# 向文件中寫入json格式數據,參數1:要寫入的數據,參數2:文件對象# json寫入數據時,默認只顯示ascii字符集的字符,非ascii字符集的字符需要轉義# 指定ensure_ascii=False可以顯示,非ascii字符集的字符json.dump(data,f,ensure_ascii=False) with open("E:/test/a.json","rt") as f:# 讀取json數據,恢復成一個字典data = json.load(f)print(type(data))print(data) # 通過序列化與反序列化,可以實現不同項目之間的數據交換 # 序列化 d = json.dumps(data,ensure_ascii=False) print(type(d)) print(d) # 反序列化 d2 = json.loads(d) print(type(d2)) print(d2)

Python中的數據類型與json格式的數據類型并非完全相符,因此,在進行轉換的時候,可能會進行一些映射處理,如下(json?-> Python):

布爾類型(true與false)映射Python中布爾類型(True與False)。

空值類型(null)映射為None。

整數與浮點類型映射為整數(int)與(float)類型。

字符串類型映射為字符串(str)類型。

數組類型([])映射為列表(list)類型。

對象類型(object)映射為字典(dict)類型

# json文件提供不同項目之間的數據交換 import json data = {"布爾類型":False,"空值類型":None,"整數與浮":2,"浮點類型":2.2,"字符串類型":"a","數組類型":[1,2,3],"對象類型":{"a":1,"b":2} } d = json.dumps(data,ensure_ascii=False) print(d) d2 = json.loads(d) print(d2)

(3)自定義類型序列化

json在序列化時,不能序列化我們自定義的類型。如果我們需要自定義的類型也能夠序列化,可以定義一個編碼類,該類繼承json.JSONEncoder,實現類中的default方法,指定序列化的方式,同時,在調用序列化方法時(dump或dumps),使用cls參數指定我們定義的編碼類。

# 自定義類型序列化 import json # 自定義的編碼類繼承json.JSONEncoder類型 class StudentEncoder(json.JSONEncoder):# 實現default方法,給出序列化形式,參數o為序列化對象def default(self, o):if isinstance(o,Student):# 將Student轉換成可序列化對象# return {"name":o.name,"age":o.age}# 返回所有屬性構成字典return o.__dict__else:# 不是Student類型,調用父類的default翻翻產生錯誤信息return super().default(0) class Student:def __init__(self,name,age):self.name = nameself.age =age s = Student("refuel",18) print(s.__dict__) # cls參數指定序列化需要用到的編碼類 jsonstr = json.dumps(s,cls=StudentEncoder) print(jsonstr)

?

3.3 pickle

pickle模塊也能序列化類型。在序列化自定義類型上,pickle可以比json模塊更加方便(不需要定義類似的編碼器類)。pickle與json在序列化上的區別如下:

序列化

json

pickle

序列化格式

文本格式,可進行正常查看。

二進制格式,不方便查看。

序列化類型的支持

支持一部分內建的類型,如果需要序列化自定義類型,需要編寫編碼類。

支持非常廣泛的類型,包括自定義類型,不需要編寫編碼類。

適用廣泛性

適用廣泛,對于序列化的內容可以用于Python語言之外的程序中進行反序列化。

適用受限,只能用于Python程序中,其他語言的程序無法反序列化。

# pickle模塊 import pickle class Student:def __init__(self,name,age):self.name = nameself.age =age s = Student("refuel",18) # pickle序列化 with open("E:/test/a.pickle","wb") as f:pickle.dump(s,f) # pickle反序列化 with open("E:/test/a.pickle","rb") as f:s2 = pickle.load(f) print(s2.name) print(s2.age)

4 上下文管理器

4.1 自定義上下文管理器

with語句跟隨的表達式會返回一個上下文管理器,該上下文管理器中定義相關方法,在with開始執行與退出時會調用,也就是說,上下文管理器為with提供一個執行環境。

__enter__(self):with語句體開始執行時,會調用該方法。可以在該方法中執行初始化操作,返回值會賦值給with語句中as后面的變量

__exit__(self, exc_type, exc_val, exc_tb):with語句體執行結束后,會調用該方法。我們在__enter__方法中執行的初始化,就可以在該方法中執行相關的清理,如,文件的關閉,線程鎖的釋等。實現finally語句同樣的功能。exc_type:產生異常的類型;exc_val:產生異常類型的對象;exc_tb:traceback類型的對象,包含了異常產生位置的堆棧調用信息。如果在with語句體中沒有產生異常,相關參數為None。

對于with,也可以關聯兩個上下文管理器,如:

with Manager1() as m1, Manager2 as m2:語句這相當于:with Manager1() as m1:with Manager2() as m2:語句

?

class MyManager:def __enter__(self):print("進入with語句體")# return selfreturn "__enter__返回值賦值給as后變量"def __exit__(self, exc_type, exc_val, exc_tb):print("離線with語句體")print(exc_type)print(exc_val)print(exc_tb) with MyManager() as f:# print(f)raise Exception("with中存在異常")

4.2?@contextmanager裝飾器

contextlib模塊中,定義了@contextmanager裝飾器,該裝飾器可以用來修飾一個生成器,從而將生成器變成一個上下文管理器,從而可以省略編寫完整的上下文管理器類。

在@contextmanager修飾的生成器中,yield之前的語句會在進入with語句體時執行(相當于__enter__方法),而yield之后的語句會在離開with語句體時執行(相當于__eixt__方法)。

with后的表達式會返回生成器對象(假設為gen_obj),進入with語句體時,內部會調用next函數,用來激活生成器對象,進而執行生成器的函數體next(gen_obj)

從而令生成器對象執行。yield產生的值則會賦值給with語句as后的變量(相當于__enter__方法的返回值)。

當with語句體結束時,如果with語句體沒有產生異常,則繼續調用next,令生成器從之前yield暫停的位置處繼續執行(這相當于實現__exit__方法)。如果with語句體產生異常,該異常會在生成器函數體yield的位置拋出。而如果生成器函數體沒有處理該異常,將會導致yield之后的語句不會得到執行,這相當于是沒有成功的執行__exit__方法。

# @contextManager修飾一個生成器,裝飾成上下文管理器 from contextlib import contextmanager # yield之前的語句會在進入with環境時執行(相當于__enter__方法) # yield產生的值賦值給as后面的變量(相當與__enter__方法的返回值) # 離開with環境,執行yield之后的語句(相當于是__exit__方法) @contextmanager def f():print("進入with環境")# 如果with語句體中產生異常,該異常會傳播到yield位置處,后面的語句不得到執行,# 所以要使用try-finally操作.根據情況捕獲,相當于實現了__exit__方法的返回值try:yield "產生的值賦值給as后面的變量"except:passfinally:print("離開with環境") with f() as f:# print(f)raise Exception("異常")

總結

以上是生活随笔為你收集整理的Python基础(十)--文件相关的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。