python?open函數(shù)中newline參數(shù)實(shí)例詳解
問(wèn)題的由來(lái)
我在讀pythoncsv模塊文檔 看到了這樣一句話
如果 csvfile 是文件對(duì)象,則打開它時(shí)應(yīng)使用 newline=‘’。
其備注:如果沒(méi)有指定 newline=‘’,則嵌入引號(hào)中的換行符將無(wú)法正確解析,并且在寫入時(shí),使用 \r\n 換行的平臺(tái)會(huì)有多余的 \r 寫入。由于 csv 模塊會(huì)執(zhí)行自己的(通用)換行符處理,因此指定 newline=‘’ 應(yīng)該總是安全的。
我就在思考o(jì)pen函數(shù)中的newline參數(shù)的作用,因?yàn)樽约褐霸谑褂胦pen函數(shù)時(shí)從來(lái)沒(méi)有設(shè)置過(guò)newline參數(shù),僅從上面官方給的備注理解newline參數(shù)可以幫助處理?yè)Q行符解析的問(wèn)題
并且查閱得知不同操作系統(tǒng)換行符并不一致:
Unix 的行結(jié)束約定 ‘\n’、Windows 的約定 ‘\r\n’ 以及舊版 Macintosh 的約定 ‘\r’
打破了我原本觀念以為的換行符就是\n
python官方文檔對(duì)newline參數(shù)解釋:
newline 控制 universal newlines 模式如何生效(它僅適用于文本模式)。它可以是 None,‘’,‘\n’,‘\r’ 和 ‘\r\n’。它的工作原理:
從流中讀取輸入時(shí),如果 newline 為 None,則啟用通用換行模式。輸入中的行可以以 ‘\n’,‘\r’ 或 ‘\r\n’ 結(jié)尾,這些行被翻譯成 ‘\n’ 在返回呼叫者之前。如果它是 ‘’,則啟用通用換行模式,但行結(jié)尾將返回給調(diào)用者未翻譯。如果它具有任何其他合法值,則輸入行僅由給定字符串終止,并且行結(jié)尾將返回給未調(diào)用的調(diào)用者。
將輸出寫入流時(shí),如果 newline 為 None,則寫入的任何 ‘\n’ 字符都將轉(zhuǎn)換為系統(tǒng)默認(rèn)行分隔符 os.linesep。如果 newline 是 ‘’ 或 ‘\n’,則不進(jìn)行翻譯。如果 newline 是任何其他合法值,則寫入的任何 ‘\n’ 字符將被轉(zhuǎn)換為給定的字符串。
從這也就理解了為什么原本使用open()寫的時(shí)候用\n就可以表示換行以及讀文本文件時(shí)行尾會(huì)返回\n
- 寫入的時(shí)候沒(méi)有指定newline參數(shù)會(huì)將\n翻譯成系統(tǒng)默認(rèn)的行分割符(\r\n)
- 讀的時(shí)候沒(méi)有指定newline參數(shù)會(huì)將行分割符(\r\n)翻譯為\n
回到上文,那為什么在讀寫csv文件時(shí)就要設(shè)置newline=''呢?
pythoncsv官方文檔解釋了這一問(wèn)題(這也就引入了第二種方法解決換行的問(wèn)題,我在后面會(huì)介紹到)
Dialect.lineterminator
放在 writer 產(chǎn)生的行的結(jié)尾,默認(rèn)為 ‘\r\n’。
注解 reader 經(jīng)過(guò)硬編碼,會(huì)識(shí)別 ‘\r’ 或 ‘\n’ 作為行尾,并忽略 lineterminator。未來(lái)可能會(huì)更改這一行為。
用白話說(shuō)就是writerow()方法在寫入一行數(shù)據(jù)時(shí)在行尾都會(huì)跟一個(gè)默認(rèn)換行符(\r\n)(即csv是將’一行數(shù)據(jù)\r\n’寫入內(nèi)存,此時(shí)這一行數(shù)據(jù)還在內(nèi)存中,還沒(méi)有寫入文件)之后執(zhí)行代碼真正在向文件寫入時(shí)根據(jù)不同newline參數(shù)進(jìn)行翻譯
而在向txt文件使用write()方法寫入內(nèi)容時(shí)是我們手動(dòng)添加換行符\n(內(nèi)存中的數(shù)據(jù)就是我們寫入的內(nèi)容,并不會(huì)隱式添加其他內(nèi)容)之后執(zhí)行代碼真正在向文件寫入時(shí)根據(jù)newline參數(shù)進(jìn)行翻譯,這就是二者的區(qū)別
具體流程:
newline=‘’
writer.writerow(‘line’) 實(shí)際是向內(nèi)存中寫入’line\r\n’ --》 執(zhí)行代碼,寫入文件,根據(jù)newline=‘’,將不進(jìn)行翻譯 --》文件最終寫入’line\r\n’
newline=None(默認(rèn))
f.write(‘line\n’) 直接將’line\n’寫入內(nèi)存 --》 執(zhí)行代碼,寫入文件,根據(jù)newline=None,將\n翻譯為\r\n --》文件最終寫入’line\r\n’

具體實(shí)例
case1: w newline=‘’ r newline=‘’
import csv
with open("test.csv","w",encoding='utf-8',newline='') as csvfile:
writer=csv.writer(csvfile)
writer.writerow(["num","name","grade"])
writer.writerows([[1,'luke','96'],[2,'jack','85'],[3,'nick','84']])
with open("test.csv","r",encoding='utf-8',newline='') as csvfile:
txtdata=csvfile.read()
txtdata #>>'num,name,grade\r\n1,luke,96\r\n2,jack,85\r\n3,nick,84\r\n'

case2: w newline=‘\r’ r newline=‘’
import csv
with open("test.csv","w",encoding='utf-8',newline='\r') as csvfile:
writer=csv.writer(csvfile)
writer.writerow(["num","name","grade"])
writer.writerows([[1,'luke','96'],[2,'jack','85'],[3,'nick','84']])
with open("test.csv","r",encoding='utf-8',newline='') as csvfile:
txtdata=csvfile.read()
txtdata #>>'num,name,grade\r\r1,luke,96\r\r2,jack,85\r\r3,nick,84\r\r'

case3: w newline=‘\r\n’ r newline=‘’
import csv
with open("test.csv","w",encoding='utf-8',newline='\r\n') as csvfile:
writer=csv.writer(csvfile)
writer.writerow(["num","name","grade"])
writer.writerows([[1,'luke','96'],[2,'jack','85'],[3,'nick','84']])
with open("test.csv","r",encoding='utf-8',newline='') as csvfile:
txtdata=csvfile.read()
txtdata #>>'num,name,grade\r\r\n1,luke,96\r\r\n2,jack,85\r\r\n3,nick,84\r\r\n'

case4: w newline=None r newline=None
import csv
with open("test.csv","w",encoding='utf-8',newline=None) as csvfile:
writer=csv.writer(csvfile)
writer.writerow(["num","name","grade"])
writer.writerows([[1,'luke','96'],[2,'jack','85'],[3,'nick','84']])
with open("test.csv","r",encoding='utf-8',newline=None) as csvfile:
txtdata=csvfile.read()
txtdata #>>'num,name,grade\n\n1,luke,96\n\n2,jack,85\n\n3,nick,84\n\n'

case5: 文件寫入為\r\r\n 文件讀取 newline=‘\r’
with open("test.csv","r",encoding='utf-8',newline='') as csvfile:
txtdata=csvfile.read()
txtdata #>>'num,name,grade\r\r\n1,luke,96\r\r\n2,jack,85\r\r\n3,nick,84\r\r\n'
import csv
with open("test.csv","r",encoding='utf-8',newline='\r') as csvfile:
content = csv.reader(csvfile)
for i in content:
print(i)

為什么會(huì)報(bào)錯(cuò):
csv.reader是如何讀取\r\r\n的:讀取時(shí)遇到\r認(rèn)為一行結(jié)束了,再一次遇到\r同樣認(rèn)為一行結(jié)束(因而返回了空串列表),遇到\n無(wú)法解釋–》報(bào)錯(cuò)
case6:文件寫入為\r\r\n 文件讀取 newline=‘\n’
with open("test.csv","r",encoding='utf-8',newline='') as csvfile:
txtdata=csvfile.read()
txtdata #>>'num,name,grade\r\r\n1,luke,96\r\r\n2,jack,85\r\r\n3,nick,84\r\r\n'
import csv
with open("test.csv","r",encoding='utf-8',newline='\n') as csvfile:
content = csv.reader(csvfile)
for i in content:
print(i)

case7:文件寫入為\r\r\n 文件讀取newline=‘\r\n’
with open("test.csv","r",encoding='utf-8',newline='') as csvfile:
txtdata=csvfile.read()
txtdata #>>'num,name,grade\r\r\n1,luke,96\r\r\n2,jack,85\r\r\n3,nick,84\r\r\n'
import csv
with open("test.csv","r",encoding='utf-8',newline='\r\n') as csvfile:
content = csv.reader(csvfile)
for i in content:
print(i)

case8:文件寫入為\r\r 文件讀取 newline=‘\r’
with open("test.csv","r",encoding='utf-8',newline='') as csvfile:
txtdata=csvfile.read()
txtdata #>>'num,name,grade\r\r1,luke,96\r\r2,jack,85\r\r3,nick,84\r\r'
import csv
with open("test.csv","r",encoding='utf-8',newline='\r') as csvfile:
content = csv.reader(csvfile)
for i in content:
print(i)

第二種方法:通過(guò)設(shè)置csv.writer方法中的lineterminator參數(shù)
上面提到lineterminator參數(shù)控制writer寫入每一行后跟的隱式結(jié)束符,默認(rèn)為’\r\n’,因此我們需要要設(shè)置lineterminator=‘\n’,讀取時(shí)也不需要設(shè)置newline參數(shù)即可獲得想要的效果
import csv
with open("test.csv","w",encoding='utf-8') as csvfile:
writer=csv.writer(csvfile,lineterminator='\n')
writer.writerow(["num","name","grade"])
writer.writerows([[1,'luke','96'],[2,'jack','85'],[3,'nick','84']])
with open("test.csv","r",encoding='utf-8') as csvfile:
lst=csv.reader(csvfile)
csvfile.seek(0)
txtdata = csvfile.read()
csvfile.seek(0)
for i in lst:
print(i)
txtdata #>>'num,name,grade\n1,luke,96\n2,jack,85\n3,nick,84\n'


總結(jié)
到此這篇關(guān)于python open函數(shù)中newline參數(shù)實(shí)例詳解的文章就介紹到這了,更多相關(guān)python open函數(shù)newline參數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python保留小數(shù)函數(shù)的幾種使用總結(jié)
本文主要介紹了python保留小數(shù)函數(shù)的幾種使用總結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02
Python 爬蟲圖片簡(jiǎn)單實(shí)現(xiàn)
這篇文章主要介紹了Python 爬蟲圖片簡(jiǎn)單實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下2017-06-06
Matplotlib實(shí)戰(zhàn)之面積圖繪制詳解
面積圖,或稱區(qū)域圖,是一種隨有序變量的變化,反映數(shù)值變化的統(tǒng)計(jì)圖表,這篇文章主要介紹了如何利用Matplotlib實(shí)現(xiàn)面積圖的繪制,需要的可以參考下2023-08-08
使用Python和大模型進(jìn)行數(shù)據(jù)分析和文本生成
Python語(yǔ)言以其簡(jiǎn)潔和強(qiáng)大的特性,成為了數(shù)據(jù)科學(xué)、機(jī)器學(xué)習(xí)和人工智能開發(fā)的首選語(yǔ)言之一,在這篇文章中,我將介紹如何用Python連接和使用大模型,并通過(guò)示例展示如何在實(shí)際項(xiàng)目中應(yīng)用這些技術(shù),需要的朋友可以參考下2024-05-05
Windows系統(tǒng)下多版本pip的共存問(wèn)題詳解
這篇文章主要給大家介紹了關(guān)于在Windows系統(tǒng)下多版本pip的共存問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-10-10
python通過(guò)cookie模擬已登錄狀態(tài)的初步研究
對(duì)于那些需要在登錄環(huán)境下進(jìn)行的爬蟲操作,模擬登陸或偽裝已登錄狀態(tài)是一個(gè)剛性需求。這篇文章主要介紹了python通過(guò)cookie模擬已登錄狀態(tài)的相關(guān)資料,需要的朋友可以參考下2016-11-11
python 讀取鼠標(biāo)點(diǎn)擊坐標(biāo)的實(shí)例
今天小編就為大家分享一篇python 讀取鼠標(biāo)點(diǎn)擊坐標(biāo)的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-12-12

