目錄
- 19. 檔案讀寫
- 19.1 檔案操作
- 19.1.1 檔案的基本操作
- 19.1.2 讀寫檔案的一般步驟
- 19.1.2.1 打開檔案
- 19.1.2.2 具體讀寫操作
- 19.1.2.3 關閉檔案
- 19.1.3 檔案物件方法
- 19.1.4 檔案物件迭代器
- 19.1.5 使用with簡化檔案操作
- 19.1.6 字串與二進制的轉化
- 19.1.6.1 將字串轉換為二進制數
- 19.1.6.2 將二進制數轉換為字串
- 19.2 json讀寫
- 19.2.1 查看json的使用方法
- 19.2.2 json 讀取
- 19.2.2.1 json.loads
- 19.2.2.2 json.load
- 19.2.3 json保存
- 19.2.3.1 dumps
- 19.2.3.2 dump
- 19.3 csv讀寫
- 19.3.1 CSV讀取
- 19.3.1.1 常規讀取
- 19.3.1.2 字典形式讀取
- 19.3.2 CSV寫入
- 19.3.2.1 常規寫入
- 19.3.2.2 字典形式寫入
- 19.3.2.3 自定義分隔符和終止符
- 19.3.3 示例專案
- 19.3.1 CSV讀取
- 19.4 YAML讀寫
- 19.4.1 YAML簡介
- 19.4.2 基本語法
- 19.4.3 資料型別
- 19.4.3.1 物件
- 19.4.3.2 陣列
- 19.4.3.3 純量
- 19.4.4 參考
- 19.4.5 應用場景
- 19.4.6 在線驗證網址:
- 19.4.7 YAML的Python讀寫
- 19.4.7.1 YAML庫安裝
- 19.4.7.2 Python寫YAML
- 19.4.7.2.1 將字典寫入YAML檔案
- 19.4.7.2.2 將串列寫入YAML檔案
- 19.4.7.3 Python讀YAML
- 19.5 Excel讀寫
- 19.5.1 安裝openpyxl模塊
- 19.5.2 讀取Excel檔案
- 19.5.2.1 使用openpyxl打開Excel檔案
- 19.5.2.2 從Workbook中獲取Sheet
- 19.5.2.3 從sheet頁中獲取單元格
- 19.5.2.4 從表中取得行和列
- 19.5.3 寫入Excel檔案
- 19.5.3.1 創建和保存Excel檔案
- 19.5.3.2 創建和洗掉sheet
- 19.5.3.3 將值寫入單元格
- 19.5.4 修飾Excel檔案
- 19.5.4.1 設定字體和樣式
- 19.5.4.2 添加公式
- 19.5.4.3 調整行高和列寬
- 19.6 物件序列化
- 19.6.1 pickle模塊方法
- 19.6.2 dumps和dump
- 19.6.2.1 dumps
- 19.6.2.2 dump
- 19.6.3 loads和load
- 19.6.3.1 loads
- 19.6.3.2 load
- 19.6.4 pickle示例
- 19.1 檔案操作
19. 檔案讀寫
19.1 檔案操作
? ? 資料持久化,是將程式中的物件以資料的方式保存到磁盤上,在程式下次運行時,可以將資料從磁盤上恢復到記憶體中,資料持久化的方式有很多,而最為常見的方式是將資料以檔案的形式保存,在Python中,可以通過內置函式的方法進行檔案的讀、寫、洗掉等操作,
19.1.1 檔案的基本操作
? ? 檔案的基本操作比較多,如創建、洗掉、修改權限、寫入、讀取等等,
- 洗掉、修改權限:作用于檔案本身,屬于系統級操作
- 讀取、寫入:是檔案最常用的操作,作用于檔案內容,屬于應用級操作
? ? 檔案的系統級操作,一般使用Python中的os、sys等模塊,
19.1.2 讀寫檔案的一般步驟
? ? 讀寫檔案一般常分為3步,每一步可使用相應的方法
- 1.打開檔案:使用open方法,回傳一個檔案物件
- 2.具體的讀寫操作:使用該檔案物件的read/write等方法
- 3.關閉檔案:使用該檔案物件的close方法
一個檔案,必須在打開之后才可以對其進行相應的操作,并在操作完成均完成進行關閉,
19.1.2.1 打開檔案
? ? 打開檔案是讀寫操作的第一步,其方法open的具體定義如下所示:
open(file, mode='r', buffering=None, encoding=None, errors=None, newline=None, closefd=True)
? ? 比較關鍵的引數如下所示:
- file:打開的檔案名,屬于字串型別,但如果檔案名含有特殊字符,需要進行轉義,
- mode:打開檔案的方式,如只讀、只寫、讀寫、二進制等等產,默認為只讀,
- encoding:如直接保存為檔案文本,需要指定編碼格式,不然會造成讀取檔案檔案出現亂碼
? ? mode的詳細介紹如下所示:
| mode | 含義 |
|---|---|
| r | 只讀,但檔案必須存在 |
| w | 只寫,如果檔案已經存在,則覆寫,不存在,則重新創建 |
| a | 以只寫的檔案打開檔案,并在檔案后追加內容,如果檔案不存在,則創建新檔案 |
| b | 以二進制形式打開,不能單獨使用 |
| + | 以讀寫形式打開檔案, 不能單獨使用 |
| r+ | 以讀寫形式打開檔案,檔案必須存在,當寫入時,會清空原內容 |
| w+ | 以讀寫形式打開檔案,檔案不存在則創建檔案,如已經存在,當寫入時,會清空原內容 |
| a+ | 以讀寫形式打開檔案,檔案不存在則創建檔案,如已經存在,當寫入時,在檔案后追加原內容 |
以上僅為常見的一些模式,實際應用還可使用組合模式,即同時使用多種模式來操作檔案,如rb、wb、wb+、ab等
? ? 另外根據作業系統的不同,又可以分為文本模式和二進制模式,其主要區別如下所示:
- 在Windows系統中,文本模式下Windows平臺的末尾換行符為\r\n,在讀取時轉換為\n,而在寫入時又將\n轉換為\r\n,這種隱藏的行為對于文本檔案是沒有問題的,但如果以文本模式打開二進制資料檔案(如圖片、EXE程式等)則會發生問題,因改變了檔案的具體內容,
- 在Unix/Linux系統中,末尾換行符為\n,因此兩者沒有區別
19.1.2.2 具體讀寫操作
? ? 通過open方法得到檔案物件后,就可以對檔案進行操作,常用的方式是讀和寫,
1.讀取檔案
? ? 通過呼叫檔案物件的read方法可以獲得檔案的內容,示例代碼如下所示:
>>> fo=open(r"C:\Surpass\a.txt","r")
>>> s=fo.read()
>>> s
? ? 打開檔案后,檔案物件fo中的read方法,會將檔案的全部內容一次性讀取到記憶體中,
2.寫入檔案
? ? 將字串寫入檔案,可以呼叫檔案物件的write方法,示例代碼如下所示:
>>> fo=open(r"C:\Surpass\a.txt","w")
>>> fo.write("Surpass")
如果檔案是以二進制形式打開,則只能以二進制形式寫入資料,
>>> fo=open(r"C:\Surpass\a.txt","wb")
>>> fo.write(b"Surpass")
19.1.2.3 關閉檔案
? ? 直接使用檔案物件的close方法即可,在打開檔案并全部操作完之后,需要及時關閉,否則會導致其他操作出錯,如洗掉、移動等,則提示檔案正在使用,
19.1.3 檔案物件方法
? ? 常見的檔案物件方法如下所示:
| 方法 | 描述 |
|---|---|
| read(size) | 讀取指定size的位元組資料,然后作為字串或bytes物件回傳,size為可選引數,如未指定,則默認檔案所有內容 |
| readline() | 讀取一行,并在字串末尾留下換行符\n,如果到檔案尾,則回傳空字串 |
| readlines() | 讀取所有行,并保存至串列中,每個元素代表一行,類似于list(fo) |
| writer(string) | 將string寫入到檔案中,回傳寫入的字符數,如果以二進制模式,則需要將string轉換為bytes物件 |
| tell() | 回傳檔案物件當前所在位置,從檔案開頭開始計算位元組數 |
| seek(offset,from_what) | 改變檔案物件所處的位置,offset是相對參考位置的偏移量,from_what表示參考位置,0-檔案頭,默認;1-當前位置;2-檔案尾 |
19.1.4 檔案物件迭代器
? ? 檔案物件本身也是一個迭代器,可以與for回圈配合進行檔案的讀取,示例如下所示:
>>> f=open("a.txt","wb+")
>>> f.write(b"name is Surpass,age is 28\n")
25
>>> f.write(b"I am learning Python")
20
>>> f.close()
>>> f=open("a.txt","r+")
>>> for content in f:
... print(content)
name is Surpass,age is 28
I am learning Python
>>> f.close()
? ? 在for回圈中,每回圈一次,相當于呼叫了一次readline方法,
19.1.5 使用with簡化檔案操作
? ? 通過以上你會發現,每次使用檔案操作,都需要3個步驟,那有沒有簡便的辦法來簡化這些操作了?Python內置了with陳述句,使用其可以簡化這種寫法,在呼叫完成之后,with陳述句會自動關閉,其語法格式如下所示:
with 運算式 as 變數:
doSomething
針對檔案操作而言,運算式就是open函式,as后面的變數就是open回傳的檔案物件,
? ? 示例代碼如下所示:
import os
filePath=os.getcwd()
filename="a.txt"
with open(os.path.join(filePath,filename),"wb+") as fo:
try:
fo.write(b"name is Surpass,age is 28\n")
fo.write(b"I am learning Python")
except Exception as ex:
print(f"write error\{ex}")
with open(os.path.join(filePath,filename),"r") as fo:
for content in fo:
print(content)
19.1.6 字串與二進制的轉化
? ? 在處理檔案操作時,常用的做法是以二進制形式保存,以檔案方式使用,一是二進制檔案更小,便于網路傳輸和存盤,另外也可以避免保存與讀取編碼不同造成的亂碼情況,
19.1.6.1 將字串轉換為二進制數
? ? bytes定義格式如下所示:
string, encoding[, errors]
? ? 示例代碼如下所示:
>>> tempA=b"name is Surpass,age is 28"
>>> tempB=bytes("name is Surpass,age is 28","utf8") # 使用utf8編碼
>>> print(f"{tempA}\n{tempB}")
b'name is Surpass,age is 28'
b'name is Surpass,age is 28'
19.1.6.2 將二進制數轉換為字串
? ? 如果將二進制數轉換為字串,可以呼叫二進制物件的decode方法,并傳入指定的解碼格式,示例如下所示:
>>> tempB=bytes("我愛中國,I love China","gb2312")
>>> print(f"{tempB}\n{tempB.decode('utf8')}\n{tempB.decode()}")
Traceback (most recent call last):
File "<input>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xce in position 0: invalid continuation byte
? ? 程式報錯了,這個問題仔細看看,就知道原因所在了,編碼使用gb2312,解碼使用了utf8,因此在做轉換時,需要避免這種情況發生,
>>> tempB=bytes("我愛中國,I love China","gb2312")
>>> print(f"{tempB}\n{tempB.decode('gb2312')}")
b'\xce\xd2\xb0\xae\xd6\xd0\xb9\xfa\xa3\xacI love China'
我愛中國,I love China
? ? Windows平臺與Linux平臺編碼解碼是有區別的,主要如下所示:
- 在Linux平臺中,生成的檔案默認編碼是utf8格式,所以解碼需要指定解碼格式應為utf8
- 在Windows平臺中,中文作業系統生成檔案默認為gb2312/gbk格式,所以解碼需要指定為相應的編碼格式才能正常解碼
為避免因作業系統不同,因此在轉換時需要顯式指定相應的編碼和解碼格式
19.2 json讀寫
? ? 在日常種類介面測驗中,會經常處理JSON格式的請求報文和回應報文等,平時用得最多的也是Python自帶的json包,其提供了4個方法dumps、dump、loads、load,
? ? 1、JSON不能存盤每一種Python值,僅能存盤以下資料型別的傳下
- 字串
- 整形
- 浮點型
- 布爾型
- 串列
- 字典
- NoneType
? ? 2、JSON不能表示Python物件,如File物件、CSV Reader、Regex物件等
19.2.1 查看json的使用方法
import json
print(json.__all__)
輸出結果為:
['dump', 'dumps', 'load', 'loads', 'JSONDecoder', 'JSONDecodeError', 'JSONEncoder']
19.2.2 json 讀取
? ? json包常用的讀取方法為loads、load,
loads:可理解為load string,其功能是將json格式的字串轉換為Python資料型別(字典)
load:讀取json檔案,將轉換為Python型別
? ? 以下分別介紹其用法
19.2.2.1 json.loads
loads常用用法如下所示:
json.loads(str,encoding='utf8')
示例如下所示:
import json
jsonStr="""{
"book":"json in action",
"author":"Surpassme",
"isbn":961839721541,
"中文名":"JSON實戰"
}"""
print(f"jsonStr type is {type(jsonStr)}")
if isinstance(jsonStr,(str,)):
result=json.loads(jsonStr,encoding="utf8")
print(f"輸出的json\n{result}")
else:
print(f"傳入的字符型別{type(jsonStr)},不是字串")
輸出結果
jsonStr type is <class 'str'>
輸出的json
{'book': 'json in action', 'author': 'Surpassme', 'isbn': 961839721541, '中文名': 'JSON實戰'}
需要注意兩點:
1、傳入的資料一定要是字符串格式,如果傳入字典則會出錯
2、建議增加字串編碼格式,防止出現亂碼
19.2.2.2 json.load
load常用用法如下所示:
json.load(jsonfile)
示例如下所示:
import json
import os
def ReadJsonFile(path,strEncode="utf8"):
try:
with open(path,"r",encoding=strEncode) as fr:
return json.load(fr)
except Exception as ex:
raise ex
if __name__=="__main__":
jsonFile=os.getcwd()+"\\jsonfile.json"
data=https://www.cnblogs.com/surpassme/p/ReadJsonFile(jsonFile)
print(f"data is\n{data}")
輸出結果
data is
{'book': 'json in action', 'author': 'Surpassme', 'isbn': 961839721541, '中文名': 'JSON實戰'}
19.2.3 json保存
? ? json包常用的讀取方法為dumps、dump,
dumps:可理解為dump string,其功能是將Python資料型別將轉換為json格式的字串
dump:將Pyhon資料保存為json檔案
19.2.3.1 dumps
dumps常用用法如下所示:
json.dumps(obj,ensure_ascii=True,indent=None)
- ensure_ascii:輸出字串是否采用ascii編碼,如果有中文,需要使用utf8編碼
- indent:輸出美化功能,一般為正數才有效
示例如下所示:
import json
jsonStr={
"book":"json in action",
"author":"Surpassme",
"isbn":961839721541,
"中文名":"JSON實戰"
}
result=json.dumps(jsonStr,ensure_ascii=False,indent=1)
print(result)
運行結果如下所示:
{
"book": "json in action",
"author": "Surpassme",
"isbn": 961839721541,
"中文名": "JSON實戰"
}
19.2.3.2 dump
dump常用用法如下所示:
json.dump(obj,file,ensure_ascii=True,indent=None)
示例如下所示:
import json
def SavaAsJsonFile(path,data,strEncode="utf8",ensure_ascii=False,indent=None):
try:
with open(path,"a",encoding=strEncode) as fw:
return json.dump(data,fw,ensure_ascii=ensure_ascii,indent=indent)
except Exception as ex:
raise ex
if __name__=="__main__":
jsonStr={
"book":"json in action",
"author":"Surpassme",
"isbn":961839721541,
"中文名":"JSON實戰"
}
path=os.getcwd()+"\\jsonfile.json"
SavaAsJsonFile(path,jsonStr,indent=1)
運行結果如下所示:
{
"book": "json in action",
"author": "Surpassme",
"isbn": 961839721541,
"中文名": "JSON實戰"
}
19.3 csv讀寫
? ? csv(Comma-Separated Values)一般是特指以逗號做為分隔符的文本檔案,因使用簡單方便,平時在測驗程序也會經常用到該型別檔案,今天就來學習一下在Python中如何處理csv檔案,
19.3.1 CSV讀取
19.3.1.1 常規讀取
讀取CSV檔案常用的步驟為,創建一個CSV檔案物件,打開檔案進行讀取
- CSV檔案如下所示:

- 示例代碼如下所示:
import csv
import os
def ReadCSVFile(path=os.getcwd(),fileName="test.csv",fileEncode="utf8"):
csvFilePath=path+"\\"+fileName
dataValue=https://www.cnblogs.com/surpassme/p/[]
if os.path.exists(csvFilePath) and os.path.isfile(csvFilePath):
try:
with open(csvFilePath,"r",encoding=fileEncode) as fr:
dataContent=csv.reader(fr)
for dataRow in dataContent:
dataValue.append(dataRow)
except Exception as ex:
raise ex
return dataValue
if __name__=="__main__":
path=r"C:\Users\Administrator\PycharmProjects\TestProject\PythonIOTest\csvLesson"
fileName="CSVTestFile.csv"
data=ReadCSVFile(path=path,fileName=fileName)
for item in data:
print(item)
- 運行結果如下所示:
['ID', 'Department', 'Employees', 'HireDate']
['1', 'Dev', 'Kevin', '2019-10-30']
['2', 'Prd', 'Lily', '2019-10-31']
['3', 'Test', 'Kate', '2019-11-01']
['4', 'Dev', 'Leo', '2019-11-02']
['5', 'Prd', 'Lucy', '2019-11-03']
['6', 'Test', 'Bruce', '2019-11-04']
['7', 'Dev', 'KK', '2019-11-05']
['8', 'Dev', 'Gaga', '2019-11-06']
['9', 'Dev', 'ABC', '2019-11-07']
['10', 'Dev', 'HBO', '2019-11-08']
19.3.1.2 字典形式讀取
? ? 如果CSV檔案第一行為標題行,余下全部為資料,則可以采用字典形式進行讀取, 以此種方式讀取時,會默認將第一行(標題)做為Key值,從第二行開始做為資料內容即Value
- 示例代碼如下所示:
import csv
import os
def ReadFromDict(path=os.getcwd(),fileName="test.csv",fileEncode="utf8"):
csvFilePath=path+"\\"+fileName
dataValue=https://www.cnblogs.com/surpassme/p/[]
if os.path.exists(csvFilePath) and os.path.isfile(csvFilePath):
try:
with open(csvFilePath,"r",encoding=fileEncode) as fr:
dataContent=csv.DictReader(fr)
headers=dataContent.fieldnames
next(dataContent)
for dataRow in dataContent:
dataValue.append(dataRow)
except Exception as ex:
raise ex
return dataValue,headers
if __name__=="__main__":
path=r"C:\Users\Administrator\PycharmProjects\TestProject\PythonIOTest\csvLesson"
fileName="CSVTestFile.csv"
data,headers=ReadFromDict(path=path,fileName=fileName)
print(f"header is {headers}")
for item in data:
outStr=f'ID is {item.setdefault("ID","Exception")},Employee name is {item.setdefault("Employees", "Exception")} \
employees\'s department {item.setdefault("Department","Exception")}'
print(outStr)
- 運行結果如下所示:
header is ['ID', 'Department', 'Employees', 'HireDate']
ID is 1,Employee name is Kevin employees's department Dev
ID is 2,Employee name is Lily employees's department Prd
ID is 3,Employee name is Kate employees's department Test
ID is 4,Employee name is Leo employees's department Dev
ID is 5,Employee name is Lucy employees's department Prd
ID is 6,Employee name is Bruce employees's department Test
ID is 7,Employee name is KK employees's department Dev
ID is 8,Employee name is Gaga employees's department Dev
ID is 9,Employee name is ABC employees's department Dev
ID is 10,Employee name is HBO employees's department Dev
19.3.2 CSV寫入
19.3.2.1 常規寫入
讀取CSV檔案常用的步驟為,創建一個CSV檔案物件,打開檔案進行寫入
- 示例代碼如下所示:
import csv
import os
def ReadCSVFile(path=os.getcwd(),fileName="test.csv",fileEncode="utf8"):
csvFilePath=path+"\\"+fileName
dataValue=https://www.cnblogs.com/surpassme/p/[]
if os.path.exists(csvFilePath) and os.path.isfile(csvFilePath):
try:
with open(csvFilePath,"r",encoding=fileEncode) as fr:
dataContent=csv.reader(fr)
for dataRow in dataContent:
dataValue.append(dataRow)
except Exception as ex:
raise ex
return dataValue
def SaveCSVFile(path=os.getcwd(),fileName="testSave.csv",fileEncode="utf8",content=""):
csvFilePath=path+"\\"+fileName
if os.path.exists(path) and os.path.isdir(path):
try:
with open(csvFilePath,'w+',encoding=fileEncode,newline="") as fw:
dataObj=csv.writer(fw)
for item in content:
dataObj.writerow(item)
except Exception as ex:
raise ex
if __name__=="__main__":
path=r"C:\Users\Administrator\PycharmProjects\TestProject\PythonIOTest\csvLesson"
print("Test save file as csv file")
data=https://www.cnblogs.com/surpassme/p/[
['ID', 'Department', 'Employees', 'HireDate'],
['1', 'Dev', 'Kevin', '2019-10-30'],
['2', 'Prd', 'Lily', '2019-10-31'],
['3', 'Test', 'Kate', '2019-11-01'],
['4', 'Dev', 'Leo', '2019-11-02'],
['5', 'Prd', 'Lucy', '2019-11-03']
]
SaveCSVFile(path=path,content=data)
dataFromSaveFile=ReadCSVFile(path=path,fileName="testSave.csv")
for item in dataFromSaveFile:
print(item)
1、如果保存的CSV檔案出現空白行,則在with open(...,newline="")增加引數newline=""
2、CSV.Writer中的方法writerow()方法接受一個串列引數,串列中的每個詞,放在輸出的CSV檔案中的一個單元格中,writerow()函式的回傳值,是寫入檔案中這一行的字符數(包含換行符)
- 運行結果如下所示:
Test save file as csv file
['ID', 'Department', 'Employees', 'HireDate']
['1', 'Dev', 'Kevin', '2019-10-30']
['2', 'Prd', 'Lily', '2019-10-31']
['3', 'Test', 'Kate', '2019-11-01']
['4', 'Dev', 'Leo', '2019-11-02']
['5', 'Prd', 'Lucy', '2019-11-03']
19.3.2.2 字典形式寫入
? ? 如果我們要創建帶有標題和資料的CSV檔案,則可以采用以字典形式進行保存檔案,
- 示例代碼如下所示:
import csv
import os
def ReadFromDict(path=os.getcwd(),fileName="test.csv",fileEncode="utf8"):
csvFilePath=path+"\\"+fileName
dataValue=https://www.cnblogs.com/surpassme/p/[]
if os.path.exists(csvFilePath) and os.path.isfile(csvFilePath):
try:
with open(csvFilePath,"r",encoding=fileEncode) as fr:
dataContent=csv.DictReader(fr)
headers=dataContent.fieldnames
next(dataContent)
for dataRow in dataContent:
dataValue.append(dataRow)
except Exception as ex:
raise ex
return dataValue,headers
def SaveCSVFileUseDict(path=os.getcwd(),fileName="testSave.csv",fileEncode="utf8",headers="",content=""):
csvFilePath=path+"\\"+fileName
if os.path.exists(path) and os.path.isdir(path):
try:
with open(csvFilePath,'w+',encoding=fileEncode,newline="") as fw:
dataObj=csv.DictWriter(fw,fieldnames=headers)
dataObj.writeheader()
for item in content:
dataObj.writerow(item)
except Exception as ex:
raise ex
if __name__=="__main__":
path=r"C:\Users\Administrator\PycharmProjects\TestProject\PythonIOTest\csvLesson"
fileName="CSVTestFile.csv"
print("Test save file as csv file")
headers={"ID", "Name", "Author", "ISBN"}
data=https://www.cnblogs.com/surpassme/p/[
{"ID":"1","Name":"Python基礎教程","Author":"Surpassme","ISBN":1088021365},
{"ID":"2","Name":"Java基礎教程","Author":"Surpassme","ISBN":2088021365},
{"ID":"3","Name":"C#基礎教程","Author":"Kevin","ISBN":3088021365},
]
SaveCSVFileUseDict(path=path,headers=headers,content=data)
dataFromSaveFile,headers=ReadFromDict(path=path,fileName="testSave.csv")
print(f"header is {headers}")
for item in dataFromSaveFile:
print(item)
以字典形式保存時,需要注意標題即為字典的Key值
- 運行結果如下所示:
Test save file as csv file
header is ['ID', 'Name', 'ISBN', 'Author']
OrderedDict([('ID', '2'), ('Name', 'Java基礎教程'), ('ISBN', '2088021365'), ('Author', 'Surpassme')])
OrderedDict([('ID', '3'), ('Name', 'C#基礎教程'), ('ISBN', '3088021365'), ('Author', 'Kevin')])
19.3.2.3 自定義分隔符和終止符
? ? 如果希望可以自定義分隔符(如Tab),希望有兩倍行距,則可以使用delimiter和lineterminator關鍵字引數,
- 示例代碼如下所示:
import csv
import os
def SaveCSVFile(path=os.getcwd(),fileName="test.csv",content="",delimiter=",",lineterminator="\n",fileEncoding="utf8"):
csvFilePath=path+"\\"+fileName
if os.path.exists(path) and os.path.isdir(path):
try:
with open(csvFilePath,"w+",encoding=fileEncoding,newline="") as fw:
dataObj=csv.writer(fw,delimiter=delimiter,lineterminator=lineterminator)
for item in content:
dataObj.writerow(item)
except Exception as ex:
raise ex
if __name__=="__main__":
path=r"C:\Users\Surpass\PycharmProjects\PythonIOTest\csvLesson"
print(f"Test save csv file")
data=https://www.cnblogs.com/surpassme/p/[
['ID', 'Department', 'Employees', 'HireDate'],
['1', 'Dev', 'Kevin', '2019-10-30'],
['2', 'Prd', 'Lily', '2019-10-31'],
['3', 'Test', 'Kate', '2019-11-01'],
['4', 'Dev', 'Leo', '2019-11-02'],
['5', 'Prd', 'Lucy', '2019-11-03']
]
SaveCSVFile(path=path,content=data,delimiter="\t",lineterminator="\n\n")
- 運行結果如下所示:

19.3.3 示例專案
? ? 假設現在有一個任務,從一個檔案夾中洗掉所有CSV檔案的第一行,主要方法如下所示:
- 依次逐個打開CSV檔案,洗掉第一行資料,再保存
- 在網上找找有沒有相應的工具
- 自己使用代碼撰寫工具
? ? 今天我們就來嘗試用Python來解決該任務,先來分析一下,使用代碼需要解決的問題點有哪些
- 過濾到檔案為CSV型別的檔案
- 讀取每個檔案的全部內容
- 洗掉CSV檔案的第一行,并保存為CSV檔案
在使用工具或代碼來修改檔案時,需要將資料或檔案進行備份
詳細示例如下所示:
import csv
import os
import shutil
def GetCSVFileList(path,extName=".csv"):
"""
獲取CSV檔案串列
"""
csvFileList=[]
for r,s,fs in os.walk(path):
for csvFile in fs:
if os.path.isfile(os.path.join(r,csvFile)) and os.path.splitext(os.path.join(r,csvFile))[-1] in extName:
csvFileList.append(os.path.join(r,csvFile))
return csvFileList
def ReadCSVFile(csvFileList,encoding="utf8"):
"""讀取CSV檔案"""
csvRows=[]
for csvFile in csvFileList:
csvFilePath=(os.path.split(csvFile))[0]+"\\headerRemoved\\"+os.path.basename(csvFile)
try:
with open(csvFile,"r",encoding=encoding) as fr:
csvObj=csv.reader(fr)
for row in csvObj:
if csvObj.line_num==1:
continue
csvRows.append(row)
WriterCSVFile(csvFilePath,csvRows)
csvRows.clear()
except Exception as ex:
raise ex
def WriterCSVFile(path,data,encoding="utf8"):
"""保存CSV檔案"""
try:
with open(path,"w+",encoding=encoding,newline="") as fw:
csvWriteObj=csv.writer(fw)
for row in data:
csvWriteObj.writerow(row)
except Exception as ex:
raise ex
def SaveAsDirectory(path,dirName):
"""創建另存檔案夾"""
tempDir=path+"\\"+dirName
try:
if os.path.isdir(tempDir) and os.path.exists(tempDir):
shutil.rmtree(tempDir)
os.makedirs(tempDir,exist_ok=True)
else:
os.makedirs(tempDir,exist_ok=True)
except Exception as ex:
raise ex
if __name__=="__main__":
path=r"C:\Users\Surpass\PycharmProjects\PythonIOTest\csvLesson\CSVFile"
SaveAsDirectory(path,"headerRemoved")
csvFiles=GetCSVFileList(path)
ReadCSVFile(csvFiles)
最終的運行效果如下所示:

19.4 YAML讀寫
19.4.1 YAML簡介
? ? YAML是YAML Ain't Markup Language的遞回縮寫,意思其實是:"Yet Another Markup Language",YAML 的語法和其他高級語言類似,并且可以簡單表達清單、散串列,標量等資料形態,它使用空白符號縮進和大量依賴外觀的特色,特別適合用來表達或編輯資料結構、各種組態檔、傾印除錯內容、檔案大綱,其擴展名為.yml.
19.4.2 基本語法
- 區分大小寫
- 使用縮進表示層級關系,同層元素左對齊
- 縮進時不允許使用Tab鍵,只允許使用空格,
- 縮進的空格數目不重要,只要相同層級的元素左側對齊即可
- 字串一般不使用引號,但必要的時候可以用引號框住
- 使用雙引號表示字串時,可用****進行特殊字符轉義
- #表示注釋
19.4.3 資料型別
- 物件:鍵值對的集合,又稱為映射(mapping)/ 哈希(hashes) / 字典(dictionary)
- 陣列:一組按次序排列的值,又稱為序列(sequence) / 串列(list)
- 純量(scalars):單個的、不可再分的值
19.4.3.1 物件
- 物件通常是鍵值對形式(key: value),冒號后面要加一個空格,示例如下所示:
key:
ckey1: cvalue1
ckey2: cvalue2
ckey3:
cckey1: ccvalue1
cckye2: ccvalue2
ckey4: cvalue4
或
key: {ckey1: cvalue1, ckey2: cvalue2,ckey3: {cckey1: ccvalue1, cckye2: ccvalue2}, ckey4: cvalue4}
- 使用?+空格表示復雜鍵,當鍵是一個串列或鍵值表時,就需要使用該符號進行表示,示例如下所示:
?
- Red
- Green
- Blue
:
- Color
以上等價于
{[blue, reg, green]: Color}
19.4.3.2 陣列
以 - 開頭的行表示構成一個陣列
- 一維陣列
- Red
- Green
- Blue
以上等價于
[ 'Red', 'Green', 'Blue' ]
- 多維陣列
-
- Red
- Green
- Blue
-
- apple
- tree
- ocean
以上等價于
[ [ 'Red', 'Green', 'Blue' ], [ 'apple', 'tree', 'ocean' ] ]
- 復雜結構
物件和陣列可以組合成更為復雜的結構,示例如下所示:
Person:
- sex:
- man
- woman
- color:
yellow: Asia
white: Europe
balck: Africa
country:
- China
- American
- South Korea
- Russia
City:
-
id: 1
name: shanghai
-
id: 2
name: beijing
以上等價于:
{
Person: [
{
sex: [ 'man', 'woman' ]
},
{
color:
{
yellow: 'Asia',
white: 'Europe',
balck: 'Africa'
}
}
],
country: [ 'China', 'American', 'South Korea', 'Russia' ],
City: [
{
id: 1,
name: 'shanghai'
},
{
id: 2,
name: 'beijing'
}
]
}
19.4.3.3 純量
純量是最基本,不能再分割的值,如下所示:
- 字串
- 布林值
- 整數
- 浮點數
- Null
- 時間
- 日期
示例如下所示:
- 字串
str:
- test str
- "test \n double " # 可以使用雙引號或者單引號包裹特殊字符,雙引號不會對特殊字符轉義,
- 'test \n double'
- line
newline # 字串可以拆成多行,每一行會被轉化成一個空格
- 'testor'' day' # 單引號之中如果還有單引號,必須連續使用兩個單引號轉義,
test: | # 多行字串可以使用|保留換行符,也可以使用 > 折疊換行
def
foo
python: >
def
foo
textblock1: |+ # + 表示保留文字塊末尾的換行,- 表示洗掉字串末尾的換行,
def
foo
textblock2: |-
def
foo
顯示結果如下所示:
str:
[ 'test str',
'test \n double ',
'test \\n double',
'line newline',
'testor\' day' ],
test: 'def\nfoo\n',
python: 'def foo \n',
textblock1: 'def\n\nfoo\n\n',
textblock2: 'def \n\nfoo' }
- 布林值
isMatch:
- true # true,True都可以
- False # false,False都可以
顯示結果如下所示:
isMatch: [ true, false ]
- 整數與浮點數
intNum:
- 123
- 0b11100011
- 0x12A
floatNum:
- 123.25
- 3.1415392e+5
顯示結果如下所示:
intNum: [ 123, 227, 298 ]
floatNum: [ 123.25, 314153.92 ]
- Null
isNull: ~ # 使用~表示null
顯示結果如下所示:
isNull: null
- 時間與日期
datetime: 2020-01-19T10:34:30+08:00 # 時間使用ISO 8601格式,時間和日期之間使用T連接,最后使用+代表時區
date: 2020-01-19 # 日期必須使用ISO 8601格式,即yyyy-MM-dd
time: 10:34:30
顯示結果如下所示:
datetime: Sun Jan 19 2020 10:34:30 GMT+0800 (中國標準時間),
date: Sun Jan 19 2020 08:00:00 GMT+0800 (中國標準時間),
time: 38070,
19.4.4 參考
錨點&和別名*,可以用來參考,示例如下所示:
server: &server
host: 10.68.1.81
username: root
password: password
test:
<<: *server
datebase: test
dev:
<<: *server
database: dev
rel:
<<: *server
database: rel
最終顯示的結果如下所示:
{
server:
{
host: '10.68.1.81',
username: 'root',
password: 'password'
},
test:
{
host: '10.68.1.81',
username: 'root',
password: 'password',
datebase: 'test'
},
dev:
{
host: '10.68.1.81',
username: 'root',
password: 'password',
database: 'dev'
},
rel:
{
host: '10.68.1.81',
username: 'root',
password: 'password',
database: 'rel'
}
}
& 用來建立錨點(server),<< 表示合并到當前資料,* 用來參考錨點,
19.4.5 應用場景
- 1、實作簡單,決議方便,特別適合在腳本語言中使用
- 2、組態檔,寫YAML比XML/ini/JSON快,因為不需要關注標簽、引號、括號等
19.4.6 在線驗證網址:
http://www.bejson.com/validators/yaml/
19.4.7 YAML的Python讀寫
19.4.7.1 YAML庫安裝
? ? 在Python常用的讀寫YAML庫有pyyaml和ruamel
- pyyaml安裝
pip install -U pyyaml
或
pip3 install -U pyyaml
- ruamel安裝
pip install -U ruamel.yaml
或
pip3 install -U ruamel.yaml
19.4.7.2 Python寫YAML
19.4.7.2.1 將字典寫入YAML檔案
示例代碼如下所示:
import os
import yaml
def SaveDict2YAML(path,filename,**data):
savePath=os.path.join(path,filename)
with open(savePath,mode="w",encoding="utf8") as fo:
yaml.dump(data,fo,Dumper=yaml.Dumper)
if __name__=="__main__":
testDict={
"server":
{
"host": "10.68.1.81",
"username": "root",
"password": "password"
},
"ower":["test","dev","rel"]
}
path=os.getcwd()
filename="dict2yaml.yaml"
SaveDict2YAML(path,filename,data=https://www.cnblogs.com/surpassme/p/testDict)
最終保存的檔案如下所示:
data:
ower:
- test
- dev
- rel
server:
host: 10.68.1.81
password: password
username: root
19.4.7.2.2 將串列寫入YAML檔案
示例代碼如下所示:
import os
import yaml
def SaveList2YAML(path,filename,data):
savePath=os.path.join(path,filename)
with open(savePath,mode="w",encoding="utf8") as fo:
yaml.dump(data,fo,Dumper=yaml.Dumper)
if __name__=="__main__":
testList=[
"test",
"dev",
"rel",
{
"server":
{
"host": "10.68.1.81",
"username": "root",
"password": "password"
}
}
]
path=os.getcwd()
filename="list2yaml.yaml"
SaveList2YAML(path,filename,testList)
最終保存的檔案如下所示:
- test
- dev
- rel
- server:
host: 10.68.1.81
password: password
username: root
19.4.7.3 Python讀YAML
import os
import yaml
import json
def ReadYAML(path,filename):
path=os.path.join(path,filename)
with open(path,mode="r",encoding="utf8") as fo:
data=https://www.cnblogs.com/surpassme/p/yaml.load(fo.read(),Loader=yaml.Loader)
return data
if __name__=="__main__":
filename="list2yaml.yaml"
path=os.getcwd()
data=https://www.cnblogs.com/surpassme/p/ReadYAML(path,filename)
print(json.dumps(data,indent=3))
最終的列印結果如下所示:
[
"test",
"dev",
"rel",
{
"server": {
"host": "10.68.1.81",
"password": "password",
"username": "root"
}
}
]
如果使用ruamel寫YAML檔案,需要將Dumper更換一下即可,如下所示:
yaml.dump(data,fo,Dumper=ruamelyaml.RoundTripDumper)
19.5 Excel讀寫
19.5.1 安裝openpyxl模塊
? ? Python沒有自帶openpyxl,需要自行安裝,安裝方法如下所示:
pip install -U openpyxl
驗證是否安裝成功
pip list | findstr "openpyxl"
或
pip show openpyxl
? ?回傳以下結果即說明安裝成功
openpyxl ? ? ? 3.0.0
19.5.2 讀取Excel檔案
? ? 以下示例將使用Excel表格 data.xlsx,使用Excel 2013創建,默認包含3個sheet頁,如下所示:

19.5.2.1 使用openpyxl打開Excel檔案
? ? 詳細代碼如下所示:
import openpyxl
import os
def getBaseDir(fileName):
return os.path.join(os.path.dirname(__file__),fileName)
def loadWorkbook():
workbook=openpyxl.load_workbook(getBaseDir("data.xlsx"))
print(type(workbook))
loadWorkbook()
openpyxl.load_workbook()接受檔案名,回傳一個workbook資料型別的值,這個workbook物件代表這個Excel檔案,需要注意的是所打開的默認必須位于當前作業目錄,否則需要傳入完整路徑,可使用 os.getcwd()
輸出結果:
<class 'openpyxl.workbook.workbook.Workbook'>
19.5.2.2 從Workbook中獲取Sheet
import openpyxl
import os
def getBaseDir(fileName):
return os.path.join(os.path.dirname(__file__),fileName)
def loadWorkbook():
workbook=openpyxl.load_workbook(getBaseDir("data.xlsx"))
return workbook
def getSheet():
wb=loadWorkbook()
# 獲取所有sheet表名
print(wb.sheetnames,type(wb.sheetnames))
# 根據sheet名字獲取sheet
print(wb['Sheet2'],type(wb['Sheet2']))
# 獲取激活的sheet
print(wb.active,type(wb.active))
if __name__ == '__main__':
getSheet()
輸出結果:
['Sheet1', 'Sheet2', 'Sheet3'] <class 'list'>
<Worksheet "Sheet2"> <class 'openpyxl.worksheet.worksheet.Worksheet'>
<Worksheet "Sheet3"> <class 'openpyxl.worksheet.worksheet.Worksheet'>
19.5.2.3 從sheet頁中獲取單元格
import openpyxl
import os
def getBaseDir(fileName):
return os.path.join(os.path.dirname(__file__),fileName)
def loadWorkbook():
workbook=openpyxl.load_workbook(getBaseDir("data.xlsx"))
return workbook
def getSheet():
wb=loadWorkbook()
# 獲取所有sheet表名
print(wb.sheetnames,type(wb.sheetnames))
# 根據sheet名字獲取sheet
print(wb['Sheet2'],type(wb['Sheet2']))
# 獲取激活的sheet
print(wb.active,type(wb.active))
def getCellValue():
wb = loadWorkbook()
sheet=wb['Sheet2']
cell=sheet['A1']
# 獲取單元格的Value值
print("Row {} Column {} Value {} ".format(cell.row,cell.column,cell.value))
for i in range(1,10):
for j in range(1,3):
print(i,sheet.cell(row=i,column=j).value)
if __name__ == '__main__':
# getSheet()
getCellValue()
輸出結果:
Row 1 Column 1 Value A1-A1
1 A1-A1
1 B1-B1
2 A1-A2
2 B1-B2
3 A1-A3
3 B1-B3
4 A1-A4
4 B1-B4
5 A1-A5
5 B1-B5
6 A1-A6
6 B1-B6
7 A1-A7
7 B1-B7
8 A1-A8
8 B1-B8
9 A1-A9
9 B1-B9
19.5.2.4 從表中取得行和列
import openpyxl
import os
def getBaseDir(fileName):
return os.path.join(os.path.dirname(__file__),fileName)
def loadWorkbook():
workbook=openpyxl.load_workbook(getBaseDir("data.xlsx"))
return workbook
def getRowAndColumn():
wb = loadWorkbook()
sheet = wb['Sheet2']
print(tuple(sheet['A1':'B8']))
# 回圈每一行
for r in sheet['A1':'B8']:
# 回圈每一列
for c in r:
print("Locate is {},value is {}".format(c.coordinate,c.value))
if __name__ == '__main__':
# getSheet()
getRowAndColumn()
運行結果如下:
((<Cell 'Sheet2'.A1>, <Cell 'Sheet2'.B1>), (<Cell 'Sheet2'.A2>, <Cell 'Sheet2'.B2>), (<Cell 'Sheet2'.A3>, <Cell 'Sheet2'.B3>), (<Cell 'Sheet2'.A4>, <Cell 'Sheet2'.B4>), (<Cell 'Sheet2'.A5>, <Cell 'Sheet2'.B5>), (<Cell 'Sheet2'.A6>, <Cell 'Sheet2'.B6>), (<Cell 'Sheet2'.A7>, <Cell 'Sheet2'.B7>), (<Cell 'Sheet2'.A8>, <Cell 'Sheet2'.B8>))
Locate is A1,value is A1-A1
Locate is B1,value is B1-B1
Locate is A2,value is A1-A2
Locate is B2,value is B1-B2
Locate is A3,value is A1-A3
Locate is B3,value is B1-B3
Locate is A4,value is A1-A4
Locate is B4,value is B1-B4
Locate is A5,value is A1-A5
Locate is B5,value is B1-B5
Locate is A6,value is A1-A6
Locate is B6,value is B1-B6
Locate is A7,value is A1-A7
Locate is B7,value is B1-B7
Locate is A8,value is A1-A8
Locate is B8,value is B1-B8
19.5.3 寫入Excel檔案
19.5.3.1 創建和保存Excel檔案
import openpyxl
import os
def CreateNewWorkbook(path,fileName="test.xlsx"):
workbook=openpyxl.Workbook()
activeSheet=workbook.active
# 給sheet取名字
activeSheet.title="This is test sheet by openpyxl"
print(f"current acvtive sheet is {activeSheet},name is: {activeSheet.title}\nwork book is {workbook['This is test sheet by openpyxl']} ")
# 保存作業簿
workbook.save(path+"\\"+fileName)
if __name__ == "__main__":
path=r"C:\Users\Surpass\PycharmProjects\PythonIOTest\ExcelLesson"
CreateNewWorkbook(path,fileName="SaveAsByOpenpyxl.xlsx")
運行結果如下所示:
current acvtive sheet is <Worksheet "This is test sheet by openpyxl">,name is: This is test sheet by openpyxl
work book is <Worksheet "This is test sheet by openpyxl">

19.5.3.2 創建和洗掉sheet
import openpyxl
import os
def CreateNewAndDelete(path,fileName="test.xlsx"):
workbook=openpyxl.Workbook()
print(f"init sheetname is:{workbook.sheetnames}")
# 創建Sheet
for i in range(5):
workbook.create_sheet(title="Sheet"+str(i),index=i)
print(f"create sheetname is {workbook.sheetnames}")
# 洗掉Sheet
for j in range(3):
del workbook['Sheet'+str(j)]
print(f"after delete sheetname is:{workbook.sheetnames}")
# 保存Excel作業簿
workbook.save(path+"\\"+fileName)
if __name__ == '__main__':
path=r"C:\Users\Surpass\PycharmProjects\PythonIOTest\ExcelLesson"
CreateNewAndDelete(path,fileName="createOrDelSheet.xlsx")
運行結果如下所示:
init sheetname is:['Sheet']
create sheetname is ['Sheet0', 'Sheet1', 'Sheet2', 'Sheet3', 'Sheet4', 'Sheet']
after delete sheetname is:['Sheet3', 'Sheet4', 'Sheet']
19.5.3.3 將值寫入單元格
import openpyxl
import os
def CreateNewAndDelete(path,fileName="test.xlsx"):
workbook=openpyxl.Workbook()
for i in range(5):
workbook.create_sheet(title="Sheet"+str(i),index=i)
# 保存Excel作業簿
workbook.save(path+"\\"+fileName)
def InsertValutToExcel(path,fileName,sheetName,insertValue,cellRange):
filePath=path+"\\"+fileName
workbook=openpyxl.load_workbook(filePath)
sheetName=workbook[sheetName]
sheetName[cellRange]=insertValue
print(sheetName[cellRange].value)
workbook.save(filePath)
if __name__ == '__main__':
path=r"C:\Users\Surpass\PycharmProjects\PythonIOTest\ExcelLesson"
CreateNewAndDelete(path,fileName="createOrDelSheet.xlsx")
InsertValutToExcel(path=path,fileName="createOrDelSheet.xlsx",sheetName="Sheet3",insertValue="https://www.cnblogs.com/surpassme/p/This is test value by openpyxl",cellRange="A3")
運行結果如下所示:

19.5.4 修飾Excel檔案
? ? 對某些單元格設定字體、樣式等,可以起到強調單元格的重要性等,因此需要從openpyxl.styles中匯入Font()和Style()函式,
19.5.4.1 設定字體和樣式
? ? 設定單元格字體樣式主要使用Font物件,向其傳入關鍵字引數即可,主要關鍵字引數如下所示:
| 關鍵字引數 | 資料型別 | 描述 |
|---|---|---|
| name | string | 字體名稱,如Arial/Times New Roman |
| size | int | 字體大小 |
| italic | bool | 是否采用斜體,True代表使用斜體 |
| bold | bool | 是否采用粗體,True代表使用粗體 |
| underline | string | 是否帶下劃線 |
| vertAlign | string | 垂直對齊方式 |
underline:為固定的引數可選項,如下所示:
- double:雙下劃線
- single:單下劃線
- doubleAccounting:會計雙下劃線
- singleAccounting:會計單下劃線
vertAlign:為固定的引數可選項,如下所示:- baseline:比較基準
- superscript:上標
- subscript:下標
示例代碼如下所示:
import os
from openpyxl import Workbook
from openpyxl.styles import colors
from openpyxl.styles import Font,Color
def SetExcelFont(path,fileName):
wb=Workbook()
sheet=wb.active
firstFontObj=Font(name="Arial",size="18",italic=True,bold=True,underline="single",color=colors.RED)
secondFontObj=Font(name="Times New Roman",size="24",bold=True,underline="double",vertAlign="baseline",color=colors.BLUE)
thirdFontObj=Font(name="Calibri",size="24",italic=False,bold=True,underline="doubleAccounting",vertAlign="superscript",color="0099CC00")
fourthFontObj=Font(name="Arial",size="34",italic=False,bold=False,underline="singleAccounting",vertAlign="subscript",color=colors.BLACK)
sheet["A1"].font=firstFontObj
sheet["B1"].font=secondFontObj
sheet["A2"].font=thirdFontObj
sheet["B2"].font=fourthFontObj
sheet["A1"]="hello"
sheet["B1"]="world"
sheet["A2"]="Software"
sheet["B2"]="Test"
wb.save(path+"\\"+fileName)
if __name__=="__main__":
path=r"C:\Users\Surpass\PycharmProjects\PythonIOTest\ExcelLesson"
SetExcelFont(path,fileName="SetExcelFont.xlsx")
運行結果如下所示:

19.5.4.2 添加公式
? ? 在Excel檔案中,公式通常以=開始,通過其他單元格的計算得到值,使用openpyxl添加公式特別簡單,就像直接在Excel檔案中添加公式一樣,現在有一份成績單,大于等于90,則評價為優,小于60為不合格,介于60和90為良好,示例代碼如下所示:
from openpyxl import load_workbook
from openpyxl import Workbook
from openpyxl.styles import Font,colors,PatternFill,fills
def AddFormula(path,fileName,sheetName="Sheet1"):
filePath=path+"\\"+fileName
wb=load_workbook(filePath)
ws=wb[sheetName]
for i in range(2,len(ws["B"])+1):
scorePost="B"+str(i)
formulaPos="C"+str(i)
formulaText=f'=IF(B{i}>=90,"優",IF(B{i}<60,"不合格","良好"))'
ws[formulaPos]=formulaText
if int(ws[scorePost].value) >=90:
# 寫入公式
ws[formulaPos].font=Font(name="Arial",color=colors.BLACK)
# 進行單元格填充
ws[formulaPos].fill=PatternFill(fill_type=fills.FILL_SOLID,fgColor=colors.GREEN)
elif int(ws[scorePost].value) <60:
ws[formulaPos].font=Font(name="Arial",color=colors.BLACK)
ws[formulaPos].fill=PatternFill(fill_type=fills.FILL_SOLID,fgColor=colors.RED)
else:
ws[formulaPos].font=Font(name="Arial",color=colors.BLACK)
ws[formulaPos].fill=PatternFill(fill_type=fills.FILL_SOLID,fgColor=colors.BLUE)
wb.save(filePath)
if __name__=="__main__":
path=r"C:\Users\Surpass\PycharmProjects\PythonIOTest\ExcelLesson"
AddFormula(path,fileName="AddFormula.xlsx")
運行的結果如下所示:

注意事項
- 如果在呼叫load_workbook()不帶引數data_only=True,則帶公式的單元格,在獲取單元格內容為其公式,如果僅希望獲取單元格值,則需要帶上data_only=True引數
19.5.4.3 調整行高和列寬
? ? 在Excel中,調整行高和列寬非常容易,今天我們來用代碼嘗試一下調整行高和列寬,主要涉及到Worksheet物件row_dimensions和column_demiensions,
示例代碼如下所示:
from openpyxl import Workbook
def SetHeightAndWidth(path,fileName="test.xlsx"):
filePath=path+"\\"+fileName
wb=Workbook()
ws=wb.active
ws["A1"]="Set Row Heigh"
ws["B1"]="Set Column Widht"
ws.row_dimensions[1].height=80
ws.column_dimensions['B'].width=50
wb.save(filePath)
if __name__=="__main__":
path=r"C:\Users\Surpass\PycharmProjects\PythonIOTest\ExcelLesson"
fileName="SetHeightAndWidth.xlsx"
SetHeightAndWidth(path,fileName=fileName)
運行結果如下所示:

19.6 物件序列化
? ? 在Python,如果需要將任意物件保存到磁盤中,必須要進行轉換為其相應的格式,如dict型別的資料是不能直接按文本格式保存的,在Python中,能實作任意物件與文本之間的相互轉化,同時也可以將任意物件與二進制之間相互轉化的稱為序列化,使用的模塊為pickle,
? ? 使用Python的pickle操作,可以將物件序列化字串、檔案等類似于檔案的任意物件;也可以將這些字串、檔案或任意類似于檔案的物件還原為原來的物件,
19.6.1 pickle模塊方法
? ? pickle模塊中,常用的方法如下所示:
- dumps:將Python中的物件序列化二進制物件
- loads:從指定的pickle資料讀取并回傳物件
- dump:將Python中的物件序列化二進制物件,并保存為檔案
- load:讀取指定的序列化資料檔案,并回傳物件
? ? 以上4個方法又可以分為兩類:
- dumps和loads:是基于記憶體的Python物件與二進制相互轉化
- dump和load:是基于檔案的Python物件與二進制相互轉化
19.6.2 dumps和dump
19.6.2.1 dumps
? ? dumps其主要功能:將Python物件轉換為二進制,方法的詳細定義如下所示:
dumps(obj, protocol=None, *, fix_imports=True)
- obj:要轉換的Python物件
- protocol:pickle的轉碼協議,取值0、1、2、3、4,默認為3,
-
- 0:ASCII碼
-
- 2:舊版本的二進制協議
-
- 3:新版本的二進制協議
-
- 4:更新版本的二進制協議
19.6.2.2 dump
? ? dumps其主要功能:將Python物件轉換為二進制檔案,方法的詳細定義如下所示:
dump(obj, file, protocol=None, *, fix_imports=True)
- obj:要轉換的Python物件
- file:序列化后要保存的檔案
- protocol:pickle的轉碼協議,取值0、1、2、3、4,默認為3,
-
- 0:ASCII碼
-
- 2:舊版本的二進制協議
-
- 3:新版本的二進制協議
-
- 4:更新版本的二進制協議
序列化的檔案擴展名為pkl
19.6.3 loads和load
19.6.3.1 loads
? ? loads其主要功能:將二進制物件轉換為Python物件,方法的詳細定義如下所示:
loads(s, *, fix_imports=True, encoding="ASCII", errors="strict")
- s:要轉換的二進制物件
? ? 在將二進制物件反序列化為Python物件時,會自動識別轉碼協議,一般不需要傳入轉碼協議引數值,當待轉換的二進制物件的位元組資料超過pickle的Python物件時,多余的位元組將被忽略,
19.6.3.2 load
? ? load其主要功能:將二進制物件檔案轉換為Python物件,方法的詳細定義如下所示:
load(file, *, fix_imports=True, encoding="ASCII", errors="strict")
- file:二進制物件檔案
19.6.4 pickle示例
1.dumps和loads
>>> import pickle
>>> tempDict={"a":1,"b":2,"c":3}
>>> pA=pickle.dumps(tempDict)
>>> pA
b'\x80\x03}q\x00(X\x01\x00\x00\x00aq\x01K\x01X\x01\x00\x00\x00bq\x02K\x02X\x01\x00\x00\x00cq\x03K\x03u.'
>>> pB=pickle.loads(pA)
>>> pB
{'a': 1, 'b': 2, 'c': 3}
2.dump和load
import os
import pickle
def saveAsPickleObj(path:str,data:str,filename="Serialization.pkl"):
savePath=os.path.join(path,filename)
try:
with open(savePath,"wb",pickle.HIGHEST_PROTOCOL) as fo:
pickle.dump(data,fo)
except Exception as ex:
print(f"save error\n{ex}")
def readPickleObj(path:str,filename):
filePath=os.path.join(path,filename)
flag= True if all((os.path.exists(filePath),os.path.isfile(filePath))) else False
if flag:
try:
with open(filePath,mode="rb") as fo:
result=pickle.load(fo)
except Exception as ex:
print(f"read error\n{ex}")
else:
return result
if __name__ == '__main__':
tempDict={"a":1,"b":2,"c":3}
path=os.getcwd()
filename="sample.pkl"
saveAsPickleObj(path,tempDict,filename)
result=readPickleObj(path,filename)
print(result)
? ? 代碼運行完成之后,會目錄生成一個sample.pkl檔案,
https://www.cnblogs.com/surpassme/p/13034972.html
本文同步在微信訂閱號上發布,如各位小伙伴們喜歡我的文章,也可以關注我的微信訂閱號:woaitest,或掃描下面的二維碼添加關注:

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/140460.html
標籤:Python
上一篇:如何使用java命令生成檔案
