Python基礎-19文件讀寫

来源:https://www.cnblogs.com/surpassme/archive/2020/06/03/13034972.html
-Advertisement-
Play Games

19. 文件讀寫 19.1 文件操作 數據持久化,是將程式中的對象以數據的方式保存到磁碟上,在程式下次運行時,可以將數據從磁碟上恢復到記憶體中。數據持久化的方式有很多,而最為常見的方式是將數據以文件的形式保存。在Python中,可以通過內置函數的方法進行文件的讀、寫、刪除等操作。 19.1.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個方法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=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=[]
    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=[]
    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=[]
    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=[
           ['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=[]
    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=[
        {"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=[
           ['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=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=yaml.load(fo.read(),Loader=yaml.Loader)
    return data

if __name__=="__main__":
    filename="list2yaml.yaml"
    path=os.getcwd()
    data=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="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
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document< ...
  • 內置對象:對象是由屬性和方法組成的,使用點語法訪問 一,array數組 1. 特點: 數組用於存儲若幹數據,自動為每位數據分配下標,從0開始 數組中的元素不限數據類型,長度可以動態調整 動態操作數組元素 :根據元素下標讀取或修改數組元素,arr[index] 2. 屬性和方法: 屬性 : lengt ...
  • 深克隆和淺克隆 淺克隆 arr.slice(0) arr.concat() let obj2 = {... obj} 深克隆 function deepClone(obj){ //判斷參數是不是一個對象 let objClone = new obj.constructor(); if(obj && ...
  • 前端的前景怎麼樣,以下是我的分享: 隨著互聯網的高速發展,不知不覺中我們的生活已被互聯網從四面八方給包圍,不管是網上點餐,網上購物、網上購票,還是網上學習,這都表明瞭現在就是互聯網的天下。因此,也就越來越多的選擇互聯網行業,選擇學習前端開發,但是大家也有擔心的問題,最近幾年web前端發展趨勢良好,但 ...
  • HTTP 請求中,空格應該被編碼為什麼?今天我們走進 RFC 文檔和 W3C 文檔,瞭解一下這個「史詩級」大坑。 ...
  • 面向介面編程能非常有效地提高代碼質量,可以將介面和實現相分離,封裝不穩定的實現,暴露穩定的介面。上游系統面向介面而非實現編程,不依賴不穩定的實現細節,這樣當實現發生變化的時候,上游系統的代碼基本上不需要做改動,以此來降低耦合性,提高擴展性。 ...
  • 背景 最近瞭解到很多朋友對限流、熔斷、降級、隔離、超時重試的概念和應用場景理解的不是很到位,所以想用五篇的篇幅稍微系統的介紹一下。 本篇是第一篇,是限流做詳解,如果反饋好的話,我會繼續寫下麵四篇。不好的話就算了,算我理解不夠,再自己總結總結。 限流的概念 有朋友問我限流和熔斷有什麼區別,我的理解很簡 ...
  • 老孟導讀:歷時1年的時間,整理完成了330+組件的詳細用法,不僅包含UI組件,還包含了功能性的組件。 雖然整理了 330+的組件基本用法,但並不是讓你每一個都學習一遍,任何技術基本都是掌握 20%就可以解決 80%的問題,因此只需學會基礎組件就可以上手項目了,至於其他的控制項只需大概瀏覽一下,做項目的 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...