Python學習筆記08——文件操作及IO流

1打開文件(獲取文件操作對象)

語法:

var f=open(filepath,mode="r",buffering=-1,encoding="",......)

filepath:爲文件路徑
mode:爲讀取模式,主要有如下操作

符號 含義 備註
r 只讀 只能讀,默認光標在文件開頭
rb 二進制只讀 以二進制讀取
r+ 讀寫 先讀後寫,開始光標在開頭,讀取操作後光標後移,繼續寫則爲中間改寫或末尾續寫
rb+ 二進制讀寫
w 只寫 只能寫入,且是複寫,無論文件是否存在,都是重新寫入。且此語句一經執行會將本存在的文件寫爲空白,無論是否開始write的動作
wb 二進制寫入 以二進制寫入
w+ 寫讀 先寫後讀,也就是文件一打開也是空白的
wb+ 二進制寫讀
a 追加 向已有文件追加內容,光標初始在文件末尾。如果文件不存在則創建新文件
ab 二進制追加 追加二進制內容
a+ 追加讀寫 光標默認在文件末尾
ab+ 二進制追加讀寫

示例:

#####r,r+,w,w+,a,a+的區別:https://www.cnblogs.com/python-coder/p/10078253.html
txt = "poem.txt"

#讀取模式
poem = open(txt,encoding="utf-8",mode="r")
print(poem.readlines())#全部讀取返回一個list,每行一個元素
print(poem.readline())#讀取一行,同時光標移動到下一行
print(poem.read())#只有a時不能讀取,可讀取模式r,r+,w+,a+,讀取所有,光標移動到最後
poem.close()#關閉流

#寫入模式
txt2="temp.txt"
temp=open(txt2,mode="w",encoding="utf-8")
temp.write("臨時文件")
temp.writelines(["第一行","第二行","第三行"])
temp.close()#關閉流

#追加模式
txt3="append.txt"
append=open(txt3,"a+",encoding="utf-8")
append.write("追加條件")#連續追加而不是換行追加
append.writelines(["第一行","第二行","第三行"])#同樣不換行
append.writelines(["第一行\n","第二行\n","第三行\n"])#手動添加換行符才能換行
append.close()#關閉流

####利用with自動關閉文件流
with open(txt,mode="r",encoding="utf-8") as reader:
    print(reader.read())

注意事項:
①文件的追加寫入都不會自動換行,需要自己在字符串中寫入“/n”
②IO流一定要關閉,否則會影響內存,同時同一文件操做的流會互相影響光標位置;
③用with open() as var:來自動關閉IO流

2.字符和字節的內存寫入

2.1StringIO

StringIO通過import io標準庫,通過創建StringIO的對象來實現對字符串存在內存的操作。對象的操作同文件操作IO流。注意點是StringIO的寫入同時光標會同步移動,寫入後不移動光標直接使用read()無法讀取文本,可以通過getValue()獲取文本。
示例:

from io import StringIO
#將字符串寫入內存而不是寫入本地硬盤 (臨時性儲存)
#操作對象只能是string,不能時Byte0

#####存入
f=StringIO()#創建一個StringIO對象
f.write("hello\n")
f.write("world\n")
print(f.read())#指標在最後,讀取爲空
print(f.getvalue())#獲取所有文本

#如此創建的光標還在頭部,可以從頭讀取
f1=StringIO("hello\nworld\n")
while True:
    s=f1.readline()
    if s:
        print(s)
    else:
        break

運行結果:

hello
world

hello

world

2.2ByteIO

ByteIO同樣屬於IO標準庫,不同之處在於ByteIO只能讀寫字節,因此需要進行編碼和解碼:
.encode()和.decode()
示例:

from io import BytesIO
#用於臨時儲存二進制文件

###存入和輸出的都是二進制符,需要編轉碼
b=BytesIO()
b.write("hello,您好".encode("utf-8"))
print(b.getvalue())
print(b.getvalue().decode("utf-8"))

運行結果:

b'hello,\xe6\x82\xa8\xe5\xa5\xbd'
hello,您好

3.序列化和反序列化

3.1二進制轉化

使用模塊pickle,序列化操作dump(obj,iostream),反序列化操作:loads(data)
序列化操作:
dump的第一個參數爲被序列化對象,第二個參數爲IO流對象,因此需要open一個io流對象
反序列化操作:
loads(data)爲數據對象,因此需要傳入IO流對象read()獲取的文本數據
代碼示例:

####序列化與反序列化(二進制)
import pickle

class Student:
    def __init__(self,id=0,name="",gender=""):
        self.id=id
        self.name=name
        self.gender=gender
    #用於更新數據,根據傳入的字典更新對象的屬性
    def config(self,entries):
        self.__dict__.update(entries)

studentA=Student(1,"小明","male")
txt = "student.txt"

#序列化操作
b = open(txt, mode="wb+")#byte模式不需要傳入編碼格式參數
pickle.dump(studentA,b)
b.close()

#反序列化操作
reader = open(txt, "rb")
f = reader.read()
student = pickle.loads(f)
print(student.id,student.name,student.gender)

運行結果:

1 小明 male

3.2JSON格式轉化

運用模塊json,運用方法dump(dict,iostream),loads(data)
序列化:
dump第一個參數需要傳入dict對象,因此需要從待序列化對象獲取其dict,直接用.__dict__可以獲取
第二個對象需要i哦stream,因此操作同二進制轉化;
反序列化:
loads返回的對象爲一個dict對象,要將其轉化爲類對象,需要通過__init__用dict對象創建類對象,或者創建初始類對象,通過dict對象修改該對象,其方法如下:

class Student:
    def __init__(self,id=0,name="",gender=""):
        self.id=id
        self.name=name
        self.gender=gender
    #用於更新數據,根據傳入的字典更新對象的屬性
    def config(self,entries):
        self.__dict__.update(entries)

代碼示例:

####序列化與反序列化(JSON文件)
import json
from  day03.Test04 import Student

studentB=Student(1,"韓梅梅","female")
studentJ="student.json"

###序列化
b= open(studentJ, "w")
stuDict = studentB.__dict__#將對象轉化爲dict對象,對應着json中的obj對象
json.dump(stuDict,b)
b.close()###############################重點!!!,必須要close掉,不然會影響後續讀取的光標位置

###反序列化
reader=open(studentJ)
f= reader.read()
#加載成字典
stDic = json.loads(f)
print(stDic)
#將字典轉化爲類對象
student=Student()
student.config(stDic)
print(student.id,student.name,student.gender)

程序運行結果:

1 韓梅梅 female
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章