主頁 > 後端開發 > Python基礎-19檔案讀寫

Python基礎-19檔案讀寫

2020-09-30 01:13:39 後端開發

目錄
  • 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.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. 檔案讀寫

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個方法dumpsdumploadsload

? ? 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包常用的讀取方法為loadsload

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包常用的讀取方法為dumpsdump

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檔案如下所示:

190201SampleCSVFile.jpg

  • 示例代碼如下所示:
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")
  • 運行結果如下所示:

190202自定義分隔符和終止符.jpg

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)

最終的運行效果如下所示:

190203專案示意圖.jpg

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庫有pyyamlruamel

  • 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頁,如下所示:

190402DefaultExcelSheet.jpg

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">

190403CreateAndSave.jpg

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")

運行結果如下所示:

190404設定字體.jpg

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")

運行的結果如下所示:

190404AddFormula.jpg

注意事項

  • 如果在呼叫load_workbook()不帶引數data_only=True,則帶公式的單元格,在獲取單元格內容為其公式,如果僅希望獲取單元格值,則需要帶上data_only=True引數
19.5.4.3 調整行高和列寬

? ? 在Excel中,調整行高和列寬非常容易,今天我們來用代碼嘗試一下調整行高和列寬,主要涉及到Worksheet物件row_dimensionscolumn_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)

運行結果如下所示:

190404SetHeightAndWidth.jpg

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,或掃描下面的二維碼添加關注:
MyQRCode.jpg

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/140460.html

標籤:Python

上一篇:如何使用java命令生成檔案

下一篇:pyecharts使用:餅形圖Pie引數說明

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more