Python模塊csv, json
〇、前言
本系列(指Python Moudules系列)每篇介紹一個(gè)或多個(gè)內(nèi)容沒(méi)有特別多模塊
模塊介紹依賴(lài)官方文檔(https://docs.python.org/zh-cn/3.8/library/index.html)或其他第三方官方文檔,主要是對(duì)其內(nèi)容的補(bǔ)充和拓展
內(nèi)容大部分來(lái)源官方文檔,少部分來(lái)源網(wǎng)絡(luò)。太過(guò)深?yuàn)W的內(nèi)容會(huì)只寫(xiě)出不介紹,或省略,或省略掉太過(guò)深?yuàn)W的部分(例如省略部分參數(shù)),或通過(guò)補(bǔ)充介紹(補(bǔ)充介紹的前面通常會(huì)有參考網(wǎng)址)
注意內(nèi)容非常依賴(lài)編號(hào)。內(nèi)容中類(lèi)的展示方式是"編號(hào)<數(shù)字>."表示類(lèi)的構(gòu)造方法(__init__),"編號(hào)<數(shù)字>.<數(shù)字>"表示類(lèi)的方法或?qū)傩裕椒ㄒ话闶菍?shí)例方法,其他方法會(huì)在前面?zhèn)渥?,屬性一般是?shí)例屬性,類(lèi)屬性會(huì)在后面?zhèn)渥?。如果?gòu)造方法無(wú)需傳參會(huì)直接展示類(lèi)名
使用Python版本3.8,但也會(huì)補(bǔ)充高版本的修改和添加內(nèi)容。系統(tǒng)Windows 7
系列WPS筆記及其他內(nèi)容的百度網(wǎng)盤(pán)鏈接:
https://pan.baidu.com/s/1fTwjyoM81_OOAccPNhGE9Q?pwd=h3fg
顏色代表含義:
淡灰色:注釋?zhuān)话闱懊嬗?
綠色:示例
橙色:拓展
紫色:示例中的input用戶(hù)輸入內(nèi)容
紅色、藍(lán)色:突出或裝飾文字作用
部分內(nèi)容可能不嚴(yán)謹(jǐn)或者錯(cuò)誤,歡迎指出

一、csv——CSV文件讀寫(xiě)
(1)、CSV文件
# 摘抄自百度百科
1.?概念
·?逗號(hào)分隔值(Comma-Separated Values,CSV,有時(shí)也稱(chēng)為字符分隔值,因?yàn)榉指糇址部梢圆皇嵌禾?hào)),其文件以純文本形式存儲(chǔ)表格數(shù)據(jù)(數(shù)字和文本)
·?純文本意味著該文件是一個(gè)字符序列,不含必須像二進(jìn)制數(shù)字那樣被解讀的數(shù)據(jù)
·?CSV文件由任意數(shù)目的記錄組成,記錄間以某種換行符分隔;每條記錄由字段組成,字段間的分隔符是其它字符或字符串,最常見(jiàn)的是逗號(hào)或制表符。通常,所有記錄都有完全相同的字段序列。通常都是純文本文件
2.?規(guī)則
·?開(kāi)頭是不留空,以行為單位
·?可含或不含列名,含列名則居文件第一行
·?一行數(shù)據(jù)不跨行,無(wú)空行
·?以半角逗號(hào)(即,)作分隔符,列為空也要表達(dá)其存在
·?列內(nèi)容如存在半角引號(hào)(即"),替換成半角雙引號(hào)("")轉(zhuǎn)義,即用半角引號(hào)(即"")將該字段值包含起來(lái)。
·?文件讀寫(xiě)時(shí)引號(hào),逗號(hào)操作規(guī)則互逆。
·?內(nèi)碼格式不限,可為 ASCII、Unicode 或者其他。
·?不支持?jǐn)?shù)字
·?不支持特殊字符
(2)、概念
csv內(nèi)置模塊實(shí)現(xiàn)了CSV格式表單數(shù)據(jù)的讀寫(xiě)。其提供了諸如“以兼容Excel的方式輸出數(shù)據(jù)文件”或“讀取Excel程序輸出的數(shù)據(jù)文件”的功能,程序員無(wú)需知道Excel所采用CSV格式的細(xì)節(jié)。此模塊同樣可以用于定義其他應(yīng)用程序可用的CSV格式或定義特定需求的CSV格式
csv內(nèi)置模塊中的reader類(lèi)和writer類(lèi)可用于讀寫(xiě)序列化數(shù)據(jù)。也可以用DictReader類(lèi)和DictWriter類(lèi)以字典的形式讀寫(xiě)數(shù)據(jù)
(3)、變種與格式參數(shù)
1.?dialect(變種)概念
為了更容易指定輸入和輸出記錄的格式(例如使用什么字符分隔),特定的一組格式參數(shù)組合為一個(gè)dialect(變種)
一個(gè)變種是Dialect類(lèi)的一個(gè)子類(lèi),它具有一組特定的方法和一個(gè)validate()方法
# validate()方法實(shí)測(cè)是驗(yàn)證變種是否有效,例如變種必須有delimiter屬性
在創(chuàng)建reader或writer對(duì)象時(shí),將某個(gè)字符串或Dialect類(lèi)的子類(lèi)指定為dialect參數(shù)。想要補(bǔ)充或覆蓋dialect參數(shù),可以再指定某些格式參數(shù)(關(guān)鍵字傳參),這些參數(shù)的名字與Dialect類(lèi)定義的屬性相同
2.?Dialect類(lèi)
Dialect類(lèi)是一個(gè)容器類(lèi),其屬性包含有如何處理雙引號(hào)、空白符、分隔符等信息。由于缺少?lài)?yán)格的CSV規(guī)格描述,不同的應(yīng)用程序會(huì)產(chǎn)生略有差別的CSV數(shù)據(jù)
Dialect(子類(lèi)的)實(shí)例定義了reader和writer實(shí)例將具有怎樣的行為
所有可用的Dialect名稱(chēng)會(huì)由函數(shù)list_dialects()返回
補(bǔ)充:容器
容器是可以包含其他對(duì)象的對(duì)象,是一種數(shù)據(jù)結(jié)構(gòu)。例如list、set等都是容器
3.?Dialect類(lèi)的屬性(格式參數(shù))
3.1.?delimiter(分隔符)
用于分隔字段的單字符,默認(rèn)為','
3.2.?escapechar(轉(zhuǎn)義符)
用于轉(zhuǎn)義單字符,默認(rèn)為None,表示禁用轉(zhuǎn)義
在寫(xiě)入時(shí),用來(lái)在quoting設(shè)置為QUOTE_NONE的情況下轉(zhuǎn)義delimiter,在doublequote設(shè)置為False的情況下轉(zhuǎn)義quotechar
在讀取時(shí),用來(lái)除去escapechar后所跟字符的任何特殊含義
# QUOTE_NONE是csv模塊的常量,具體見(jiàn)后
3.3.?quotechar(引號(hào)字符)
用于包住含有特殊字符的字段的單字符,默認(rèn)為雙引號(hào)
# 此章所說(shuō)的“特殊字符”指delimiter、quotechar、lineterminator等字符
3.4.?doublequote
控制出現(xiàn)在字段中的quotechar本身應(yīng)如何被引出,默認(rèn)為T(mén)rue。為T(mén)rue時(shí),雙寫(xiě)quotechar;為False時(shí),在quotechar前面放置escapechar
在寫(xiě)入時(shí),如果doublequote是False,且沒(méi)有定義escapechar,則在字段中發(fā)現(xiàn)quotechar時(shí)拋出Error異常
# Error異常是csv模塊的異常
3.5.?lineterminator(換行符)
放在writer產(chǎn)生的行的結(jié)尾,默認(rèn)為'\r\n'
# reader經(jīng)過(guò)硬編碼,會(huì)識(shí)別'\r'或'\n'作為行的結(jié)尾,并忽略lineterminator
3.6.?quoting
控制writer何時(shí)生成引號(hào),以及reader何時(shí)識(shí)別引號(hào),值可以是任何模塊內(nèi)QUOTE_開(kāi)頭的常量,默認(rèn)為QUOTE_MINIMAL
3.7.?skipinitialspace
如果為T(mén)rue,則忽略delimiter之后的空格。默認(rèn)為False
3.8.?strict
如果為T(mén)rue,則在輸入錯(cuò)誤的CSV是拋出Error異常。默認(rèn)為False
# 實(shí)測(cè)Dialect類(lèi)的子類(lèi)必須定義delimiter, quoting, lineterminator屬性,在quoting不為QUOTE_NONE時(shí)還需定義quotechar
補(bǔ)充:這里的默認(rèn)值是指excel變種相應(yīng)格式參數(shù)的值以及使用register_dialect()時(shí)的默認(rèn)值
(4)、常量
1.?QUOTE_ALL
指示writer對(duì)象為所有字段加上引號(hào)
2.?QUOTE_MINIMAL
指示writer對(duì)象僅為包含特殊字符的字段加上引號(hào)
3.?QUOTE_NONNUMERIC
指示writer對(duì)象為所有非數(shù)字字段加上引號(hào)
指示reader對(duì)象為所有未用引號(hào)引出的字段轉(zhuǎn)換為float類(lèi)型
4.?QUOTE_NONE
指示writer對(duì)象不使用引號(hào)引出字段
# 在寫(xiě)入時(shí),delimiter前面應(yīng)該有escapechar。如果未設(shè)置escapechar,則遇到任何需要轉(zhuǎn)義的字符時(shí),writer都會(huì)拋出Error異常
指示reader對(duì)象不對(duì)引號(hào)字符進(jìn)行特殊處理
(5)、函數(shù)
1.?reader(csvfile, dialect='excel', **fmtparams)
返回一個(gè)reader對(duì)象,該對(duì)象將逐行遍歷csvfile
csvfile——可以是任何支持迭代器協(xié)議(iterator協(xié)議)并在每次調(diào)用__next__()方法時(shí)都返回字符串的對(duì)象,例如文件對(duì)象和列表
# 如果csvfile是文件對(duì)象,則open()的newline參數(shù)應(yīng)是'',因?yàn)槿绻麤](méi)指定newline,則嵌入引號(hào)中的換行符將無(wú)法正確解析,且在寫(xiě)入時(shí),使用'\r\n'換行的平臺(tái)會(huì)有多余的'\r'寫(xiě)入
dialect——用于不同的CSV變種的特定參數(shù)組。可以是Dialect類(lèi)的子類(lèi)的實(shí)例或list_dialects()函數(shù)返回的字符串之一
# 實(shí)測(cè)也可以是Dialect類(lèi)的子類(lèi)
fmtparams——可以覆寫(xiě)當(dāng)前變種格式中的單個(gè)格式設(shè)置。具體見(jiàn)(3)、變種與格式參數(shù)
csv文件的每一行讀取為一個(gè)字符串組成的列表,不會(huì)執(zhí)行自動(dòng)數(shù)據(jù)類(lèi)型轉(zhuǎn)換
補(bǔ)充:迭代器協(xié)議
對(duì)象必須提供一個(gè)__next__()方法,且執(zhí)行該方法要么返回迭代器中的下一項(xiàng),要么就引起StopIteration異常終止迭代
2.?writer(csvfile, dialect='excel', **fmtparams)
返回一個(gè)writer對(duì)象,該對(duì)象負(fù)責(zé)將用戶(hù)的數(shù)據(jù)在給定的文件類(lèi)對(duì)象上轉(zhuǎn)換為帶分隔符的字符串
csvfile——可以是任何具有write()方法的對(duì)象
# 如果csvfile是文件對(duì)象,則open()的newline參數(shù)應(yīng)是'',原因見(jiàn)上
dialect, fmtparams:同reader()
None值會(huì)被當(dāng)作空字符串寫(xiě)入,其他非字符串?dāng)?shù)據(jù)都會(huì)先用str()轉(zhuǎn)換為字符串再寫(xiě)入,原因見(jiàn)官方文檔
示例:
運(yùn)行結(jié)果:
['a', 'a', 'a', 'a', 'a', 'b', 'b', 'b', 'b', 'b']
['a', 'a', 'a', 'a', 'a', 'b', 'b', 'b', 'b', 'b']
['a', 'a', 'a', 'a', 'a', 'b', 'b', 'b', 'b', 'b']
['a', 'a', 'a', 'a', 'a', 'b', 'b', 'b', 'b', 'b']
a.csv文件:
a,a,a,a,a,b,b,b,b,b
a,a,a,a,a,b,b,b,b,b
b.csv文件:
/a/|/a/|/a/|/a/|/a/|/b/|/b/|/b/|/b/|/b/
/a/|/a/|/a/|/a/|/a/|/b/|/b/|/b/|/b/|/b/
3.?register_dialect(name[, dialect[, **fmtparams]])
將name和dialect關(guān)聯(lián)起來(lái)
# 也就是將name添加進(jìn)變種注冊(cè)表,注冊(cè)后的變種在使用writer()和reader()方法時(shí)可以傳入字符串name
name——必須是字符串
dialect——Dialect類(lèi)的子類(lèi)或其子類(lèi)的實(shí)例
fmtparams——覆寫(xiě)當(dāng)前變種格式中的單個(gè)格式設(shè)置
如果沒(méi)有指定dialect, fmtparams,則會(huì)使用格式參數(shù)的默認(rèn)值
4.?unregister_dialect(name)
從變種注冊(cè)表中刪除name對(duì)應(yīng)的變種
如果name不是已注冊(cè)的變種名稱(chēng),則拋出Error異常
5.?get_dialect(name)
返回name對(duì)應(yīng)的變種。此函數(shù)返回的Dialect對(duì)象不可變
如果name不是已注冊(cè)的變種名稱(chēng),則拋出Error異常
6.?list_dialects()
返回所有已注冊(cè)變種的名稱(chēng)
7.?field_size_limit([new_limit])
返回解析器當(dāng)前允許的最大字段大小
new_limit——如果指定,則它稱(chēng)為新的最大字段大小
# 實(shí)測(cè)值為131072
(6)、Reader對(duì)象
1.?概念
Reader對(duì)象包括DictReader實(shí)例和reader()函數(shù)返回的對(duì)象
2.?DictReader(f, fieldnames=None, restkey=None, restval=None, dialect='excel', *args, **kwds)
創(chuàng)建一個(gè)對(duì)象,該對(duì)象在操作上類(lèi)似于常規(guī)reader,但是將每行中的信息映射到一個(gè)字典,該字典的鍵由可選參數(shù)fieldnames給出
# 這里的字典像是{此列的標(biāo)題: 此列的單元格}——以第一行的標(biāo)題(或fieldnames參數(shù))為鍵,其他的每行對(duì)應(yīng)標(biāo)題列下的單元格為值
# 也就是{字段名: 字段值}
f——同reader()的csvfile參數(shù)
fieldnames——是一個(gè)序列。如果省略,則以文件f第一行中的值將用作字段名。無(wú)論字段名是如何確定的,字典都將保留其原始順序
# 這里個(gè)人理解的原始順序是傳入字典鍵的順序是怎樣的,for-in語(yǔ)句讀取鍵的順序就是怎樣的
如果某一行中的字段多于字段名,則使用restkey(默認(rèn)為None)指定的字段名作為鍵,剩余數(shù)據(jù)會(huì)被放入一個(gè)列表作為值,添加進(jìn)字典
如果某一行(非空白行)的字段少于字段名,則缺失的字段值會(huì)使用restval(默認(rèn)為None)的值來(lái)填充
dialect, args, kwds——傳遞給底層的reader()
3.?Reader對(duì)象公開(kāi)方法和屬性
3.1.?__next__()
返回reader的可迭代對(duì)象的下一行,返回值是一個(gè)列表(如果對(duì)象是由reader()返回)或字典(如果對(duì)象是一個(gè)DictReader實(shí)例),根據(jù)當(dāng)前變種來(lái)解析
# 通常以next()的形式調(diào)用,使用for-in語(yǔ)句可以進(jìn)行迭代
3.2.?dialect屬性
變種描述,只讀,供解析器使用
3.3.?line_num屬性
源迭代器已經(jīng)讀取了的行數(shù)。它與返回的記錄數(shù)不同,因?yàn)橛涗浛赡芸缭蕉嘈?/span>
4.?DictReader對(duì)象公開(kāi)屬性
4.1.?fieldnames屬性
字段名稱(chēng)。如果在創(chuàng)建對(duì)象時(shí)未傳入字段名稱(chēng),則首次訪問(wèn)時(shí)或從文件中讀取第一條記錄時(shí)會(huì)初始化此屬性
示例:
創(chuàng)建一個(gè)目錄,目錄創(chuàng)建a.csv和main.py文件
a.csv文件:
姓名,班級(jí),語(yǔ)文,數(shù)學(xué),英語(yǔ)
A,三、(1),74,84,55
B,三、(1),95,91
C,三、(1),85,89,72
D,三、(1),86,56,78,120,150
main.py文件:
運(yùn)行main.py結(jié)果:
['姓名', '班級(jí)', '語(yǔ)文', '數(shù)學(xué)', '英語(yǔ)']
{'姓名': 'A', '班級(jí)': '三、(1)', '語(yǔ)文': '74', '數(shù)學(xué)': '84', '英語(yǔ)': '55'}
{'姓名': 'B', '班級(jí)': '三、(1)', '語(yǔ)文': '95', '數(shù)學(xué)': '91', '英語(yǔ)': '缺失'}
{'姓名': 'C', '班級(jí)': '三、(1)', '語(yǔ)文': '85', '數(shù)學(xué)': '89', '英語(yǔ)': '72'}
{'姓名': 'D', '班級(jí)': '三、(1)', '語(yǔ)文': '86', '數(shù)學(xué)': '56', '英語(yǔ)': '78', '多余數(shù)據(jù)': ['120', '150']}
5
(7)、Writer對(duì)象
1.?概念
Writer對(duì)象包括DictWriter實(shí)例和writer()函數(shù)返回的對(duì)象
對(duì)于writer()函數(shù)返回的對(duì)象,行必須是可迭代對(duì)象;對(duì)于DictWriter實(shí)例,行必須是一個(gè)字典(這個(gè)字典將字段名映射到字段值)
注意寫(xiě)入的復(fù)數(shù)會(huì)被括號(hào)包圍
2.?DictWriter(f, fieldnames, restval='', extrasaction='raise', dialect='excel', *args, **kwds)
創(chuàng)建一個(gè)對(duì)象,該對(duì)象在操作上類(lèi)似于常規(guī)writer,但會(huì)將字典映射到輸出行
f——同reader()的csvfile參數(shù)
fieldnames——是由鍵組成的序列,指定傳遞給writerow()的字典中值被寫(xiě)入文件f的順序
# 注意fieldnames不是可選參數(shù)
如果傳遞給writerow()的字典缺少fieldnames中的鍵,則可選參數(shù)restval(默認(rèn)為空字符串)指定鍵要寫(xiě)入的值
如果傳遞給writerow()的字典的某些鍵在fieldnames中找不到,則可選參數(shù)extrasaction(默認(rèn)為'raise')用于指定要執(zhí)行的操作。如果值為'raise'則會(huì)引發(fā)ValueError異常;如果值為'ignore',則忽略多出的鍵
dialect, args, kwds——傳遞給底層的writer()
3.?Writer對(duì)象公開(kāi)方法和屬性
3.1.?writerow(row)
將row寫(xiě)入到writer的文件對(duì)象,根據(jù)當(dāng)前變種進(jìn)行格式化。返回對(duì)下層文件對(duì)象的write方法調(diào)用的返回值
# 如果writer是writer()函數(shù)返回的對(duì)象,則可迭代對(duì)象row作為一行,其中的每一個(gè)元素作為一個(gè)字段。如果writer是DictWriter的實(shí)例,則字典row作為一行,其中鍵值對(duì)處理見(jiàn)上文
3.2.?writerows(rows)
rows是能迭代出多個(gè)上述row對(duì)象的迭代器,會(huì)將rows中的所有元素寫(xiě)入writer的文件對(duì)象,根據(jù)當(dāng)前變種進(jìn)行格式化
# 可迭代對(duì)象rows的每一個(gè)元素作為一行
3.3.?dialect屬性
變種描述,只讀,供writer使用
4.?DictWriter對(duì)象公開(kāi)方法
4.1.?writeheader()
寫(xiě)入一行字段名稱(chēng)(構(gòu)造方法傳入的fieldnames參數(shù))到writer的文件對(duì)象中,根據(jù)當(dāng)前變種進(jìn)行格式化。此方法的返回值是內(nèi)部使用的writerow()的返回值
示例:
運(yùn)行結(jié)果:
a.csv文件:
姓名,班級(jí),語(yǔ)文,數(shù)學(xué),英語(yǔ)
A,三、(1),74,84,55
B,三、(1),95,91,缺失
C,三、(1),85,89,72
D,三、(1),86,56,78
(8)、內(nèi)置變種
1.?excel
定義了Excel生成的CSV文件的常規(guī)屬性。它在變種注冊(cè)表中的名稱(chēng)是'excel'
格式參數(shù)的值就是默認(rèn)值
2.?excel_tab
定義了Excel生成的、制表符分隔的CSV文件的常規(guī)屬性。它在變種注冊(cè)表中的名稱(chēng)是'excel-tab'
格式參數(shù)與excel的區(qū)別是分隔符是'\t'
3.?unix_dialect
定義了在UNIX系統(tǒng)上生成的CSV文件的常規(guī)屬性。它在變種注冊(cè)表中的名稱(chēng)是'unix'
格式參數(shù)與excel的區(qū)別是換行符使用'\n'以及quoting值為QUOTE_ALL
(9)、Sniffer類(lèi)
1.?作用
用于推斷CSV文件的格式
2.?方法
2.1.?sniff(sample, delimiters=None)
分析給定文本sample并返回一個(gè)Dialect子類(lèi),該子類(lèi)中包含了分析出的格式參數(shù)
delimiters——該參數(shù)會(huì)被解釋為字符串,該字符串包含了可能有效的分隔符
2.2.?has_header(sample)
分析給定文本sample(假定為CSV格式),如果發(fā)現(xiàn)其首行為一組列標(biāo)題則返回True。在檢查每一列時(shí),將考慮是否滿足兩個(gè)關(guān)鍵標(biāo)準(zhǔn)之一來(lái)估計(jì)sample是否包含標(biāo)題:
·?第二至第n行包含數(shù)字值
·?第二至第n行包含字符串值,其中至少有一個(gè)值的長(zhǎng)度與該列預(yù)期標(biāo)題的長(zhǎng)度不同
會(huì)對(duì)第一行之后的二十行進(jìn)行采樣;如果有超過(guò)一半的列+行符合標(biāo)準(zhǔn),則返回True
# 此方法是一個(gè)粗略的啟發(fā)式方式,有可能產(chǎn)生錯(cuò)誤的真值和假值
補(bǔ)充:?jiǎn)l(fā)式方法 ?# 摘抄自百度百科
啟發(fā)式方法指人在解決問(wèn)題時(shí)所采取的一種根據(jù)經(jīng)驗(yàn)規(guī)則進(jìn)行發(fā)現(xiàn)的方法
示例:
運(yùn)行結(jié)果:
/
True
二、json——JSON編碼和解碼器
(1)、JSON
# 摘編自菜鳥(niǎo)教程:https://www.runoob.com/json/json-tutorial.html
1.?概念
·?JSON指的是JavaScript對(duì)象表示法(Java Script Object Notation)
·?JSON是輕量級(jí)的文本數(shù)據(jù)交換格式
·?JSON獨(dú)立于語(yǔ)言:JSON使用Javascript語(yǔ)法來(lái)描述數(shù)據(jù)對(duì)象,但是JSON仍然獨(dú)立于語(yǔ)言和平臺(tái)。JSON解析器和JSON庫(kù)支持許多不同的編程語(yǔ)言
·?JSON具有自我描述性,更易理解
# 自我描述性也就是易于人閱讀和編寫(xiě)
·?JSON是純文本
·?JSON比XML更小、更快,更易解析
·?JSON 具有層級(jí)結(jié)構(gòu)(值中存在值)
2.?語(yǔ)法
·?數(shù)據(jù)在鍵/值對(duì)中
·?數(shù)據(jù)由逗號(hào),分隔
·?使用斜杠\來(lái)轉(zhuǎn)義字符
·?大括號(hào){}保存對(duì)象
·?中括號(hào)[]保存數(shù)組,數(shù)組可以包含多個(gè)對(duì)象
3.?JSON值
·?數(shù)字(整數(shù)或浮點(diǎn)數(shù))
·?字符串(在雙引號(hào)中)
·?邏輯值(true或false) ?# 注意是小寫(xiě)
·?數(shù)組(在中括號(hào)中)
·?對(duì)象(在大括號(hào)中)
·?null ?# 相當(dāng)于Python中的None
4.?JSON鍵/值對(duì)(名稱(chēng)/值對(duì))
·?key必須是字符串,value可以是合法的JSON數(shù)據(jù)類(lèi)型(上面提到的六個(gè))
·?key和value中使用冒號(hào):分隔
·?每個(gè)鍵/值對(duì)使用逗號(hào),分隔
5.?JSON的兩種結(jié)構(gòu)
5.1.?對(duì)象
JSON對(duì)象在大括號(hào){}中書(shū)寫(xiě),是一個(gè)無(wú)序的鍵/值對(duì)集合
5.2.?數(shù)組
JSON數(shù)組在中括號(hào)[]中書(shū)寫(xiě),是一個(gè)有序的值集合
# 值之間使用逗號(hào),分隔
# 對(duì)象之間可以嵌套,數(shù)組之間也可以嵌套
6.?JSON文件
·?JSON文件的文件類(lèi)型是.json
·?JSON文本的MIME類(lèi)型是application/json
(2)、概念
json內(nèi)置模塊(嚴(yán)格來(lái)說(shuō)是一個(gè)包)用于對(duì)JSON數(shù)據(jù)進(jìn)行編解碼
# 解析不信任JSON數(shù)據(jù)時(shí)要小心,惡意的JSON字符串可能導(dǎo)致解碼器消耗大量的CPU和內(nèi)存資源,建議限制要解析的數(shù)據(jù)的大小
(3)、轉(zhuǎn)換表
1.?Python編碼為JSON類(lèi)型轉(zhuǎn)換對(duì)應(yīng)表
?

2.?JSON解碼為Python類(lèi)型轉(zhuǎn)換對(duì)應(yīng)表

# 這個(gè)模塊的編碼器和解碼器默認(rèn)保護(hù)輸入和輸出的順序。僅當(dāng)?shù)讓拥娜萜魑磁判驎r(shí)才會(huì)失去順序
1.?dump(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)
使用“(3)、1”轉(zhuǎn)換表將obj序列化為JSON格式化流到fp
obj——對(duì)象
fp——支持.write()方法的文件對(duì)象
# json模塊始終產(chǎn)生str對(duì)象而非bytes對(duì)象。因此fp.write()必須支持str輸入
# 以下參數(shù)只能使用關(guān)鍵字傳參
skipkeys——如果為T(mén)rue(默認(rèn)值為False),則不是基本對(duì)象的字典的鍵會(huì)被跳過(guò);否則引發(fā)一個(gè)TypeError
# 這里“基本對(duì)象”包括str, int, float, bool或None
ensure_ascii——如果為T(mén)rue(默認(rèn)值),則輸出保證將所有輸入的非ASCII字符轉(zhuǎn)義(例如'Ⅰ'轉(zhuǎn)義成'\u2160')。如果為False,則這些字符會(huì)原樣輸出
check_circular——如果為False(默認(rèn)值為T(mén)rue),則容器類(lèi)型的循環(huán)引用檢驗(yàn)會(huì)被跳過(guò)
補(bǔ)充:循環(huán)引用
A對(duì)象引用B對(duì)象,B對(duì)象又引用A對(duì)象。這會(huì)導(dǎo)致RecursionError(或者更糟)
allow_nan——如果為False,則在對(duì)嚴(yán)格JSON規(guī)格范圍外的float類(lèi)型值(nan、inf和-inf)進(jìn)行序列化時(shí)會(huì)引發(fā)一個(gè)ValueError。如果為T(mén)rue(默認(rèn)值),則使用它們的JavaScript等價(jià)形式(NaN、Infinity和-Infinity)
indent——如果值為一個(gè)非負(fù)整數(shù)或者字符串,則JSON數(shù)組元素和對(duì)象成員會(huì)被以指定的縮進(jìn)等級(jí)美化輸出:
如果indent為零、負(fù)數(shù)或空字符串,則只會(huì)添加換行符
如果indent為正整數(shù),則會(huì)讓每一層縮進(jìn)同樣數(shù)量的空格
如果indent為一個(gè)字符串,則那個(gè)字符串會(huì)被用于縮進(jìn)沒(méi)一層
如果indent為None(默認(rèn)值),則會(huì)選擇最緊湊的表達(dá)
separators——指定數(shù)組和對(duì)象的分隔符,是一個(gè)(數(shù)組分隔符, 對(duì)象分隔符)元組
當(dāng)indent為None時(shí),默認(rèn)值取(', ', ': '),否則取(',', ': ')
# 使用(',', ':')獲得最緊湊的JSON表達(dá)式
default——是一個(gè)函數(shù),當(dāng)某個(gè)對(duì)象無(wú)法被序列化時(shí)它會(huì)被調(diào)用。它應(yīng)該返回該對(duì)象的一個(gè)可以被JSON編碼的版本或者引發(fā)一個(gè)TypeError。如果沒(méi)有被指定(默認(rèn)值),則會(huì)直接引發(fā)TypeError
sort_keys——如果為T(mén)rue(默認(rèn)值為False),則字典的輸出會(huì)以鍵的順序排序
# 這里的“輸出”指寫(xiě)入文件fp
cls——自定義的JSONEncoder子類(lèi)(JSON編碼器),使用此參數(shù)指定這個(gè)自定義子類(lèi);否則使用JSONEncoder
kw——當(dāng)使用自定義的JSONEncoder子類(lèi)時(shí)傳入的額外的關(guān)鍵字參數(shù)
2.?dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)
使用“(3)、1”轉(zhuǎn)換表將obj序列化為JSON格式化的str
參數(shù)的含義與dump()中的相同
# 此函數(shù)與dump()的區(qū)別是不是寫(xiě)入到文件而是返回序列化后的字符串
# JSON中鍵值對(duì)的鍵永遠(yuǎn)是str類(lèi)型的。當(dāng)一個(gè)對(duì)象被轉(zhuǎn)化為JSON時(shí),字典中的所有鍵都會(huì)強(qiáng)制轉(zhuǎn)換為字符串
示例:
運(yùn)行結(jié)果:
{"name":["a","b","\u0393"],"value":{"c":false,"d":null,"a":1,"b":2.2,"e":Infinity}}
{"name":["a","b","\u0393"],"value":{"a":1,"b":2.2,"c":false,"d":null,"e":Infinity}}
# 當(dāng)sort_keys為T(mén)rue時(shí),字典按鍵排序
a.json文件: ?# 美化輸出,使用4個(gè)空格縮進(jìn)
{
????"name": [
????????"a",
????????"b",
????????"\u0393"
????],
????"value": {
????????"c": false,
????????"d": null,
????????"a": 1,
????????"b": 2.2,
????????"e": Infinity
????}
}
3.?load(fp, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
使用“(3)、2”轉(zhuǎn)換表將fp反序列化為一個(gè)Python對(duì)象
fp——支持.read()方法并包含一個(gè)JSON文檔的文件對(duì)象(文本文件或二進(jìn)制文件)
# 以下參數(shù)只能使用關(guān)鍵字傳參
# 下面兩個(gè)參數(shù)能夠被用于實(shí)現(xiàn)自定義解碼器
object_hook——是一個(gè)可選函數(shù),它會(huì)被每一個(gè)解碼出的對(duì)象字面值(即一個(gè)dict)調(diào)用并傳參,傳參是對(duì)象字面值。此函數(shù)的返回值會(huì)取代原本的dict
object_pairs_hook——是一個(gè)可選函數(shù),他會(huì)被每一個(gè)解碼出的對(duì)象字面值調(diào)用并傳參,傳參是對(duì)象字面值組成的有序列表:[(鍵1, 值1), (鍵2, 值2)...]。此函數(shù)的返回值會(huì)取代原本的dict。如果object_hook也被定義,object_pairs_hook優(yōu)先
parse_float——需要解碼JSON浮點(diǎn)數(shù)的字符串時(shí)自動(dòng)調(diào)用的函數(shù),傳入需解碼的字符串,返回值取代原本值。默認(rèn)狀態(tài)下,相當(dāng)于float(num_str)
# num_str是需解碼的字符串
# 可以用于對(duì) JSON 浮點(diǎn)數(shù)使用其它數(shù)據(jù)類(lèi)型和語(yǔ)法分析程序
parse_int——需要解碼JSON整數(shù)的字符串時(shí)自定調(diào)用的函數(shù),傳入需解碼的字符串,返回值取代原本值。默認(rèn)狀態(tài)下,相當(dāng)于int(num_str)
# 可以用于對(duì) JSON 整數(shù)使用其它數(shù)據(jù)類(lèi)型和語(yǔ)法分析程序
parse_constant——解碼遇到字符串'-Infinity', 'Infinity', 'NaN'時(shí)自動(dòng)調(diào)用的函數(shù),傳入遇到的字符串,返回值取代原本值
# 遇到無(wú)效的JSON數(shù)字可以使用它引發(fā)異常
cls——自定義的JSONDecoder子類(lèi)(JSON解碼器),使用此參數(shù)指定這個(gè)自定義子類(lèi);否則使用JSONDecoder
kw——當(dāng)使用自定義的JSONDecoderr子類(lèi)時(shí)傳入的額外的關(guān)鍵字參數(shù)
如果反序列化的數(shù)據(jù)不是有效JSON文檔,則會(huì)引發(fā)JSONDecodeError
4.?loads(s, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
使用“(3)、2”轉(zhuǎn)換表將s反序列化為一個(gè)Python對(duì)象
s——一個(gè)包含JSON文檔的str, bytes或bytearray實(shí)例
其他參數(shù)的含義與load()中的相同
如果反序列化的數(shù)據(jù)不是有效JSON文檔,則會(huì)引發(fā)JSONDecodeError
示例:
運(yùn)行結(jié)果:
函數(shù)被調(diào)用,傳入?yún)?shù): 1
函數(shù)被調(diào)用,傳入?yún)?shù): 2.2
函數(shù)被調(diào)用,傳入?yún)?shù): Infinity
函數(shù)被調(diào)用,傳入?yún)?shù): [('f', '1'), ('g', '2.2'), ('h', 'Infinity')]
['a', 'b', ['c', 'd', 'e'], [('f', '1'), ('g', '2.2'), ('h', 'Infinity')], 'i']
(5)、編碼器和解碼器(類(lèi))
1.?JSONEncoder(*, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None)
用于Python數(shù)據(jù)結(jié)構(gòu)的可擴(kuò)展JSON編碼器
# 默認(rèn)支持的對(duì)象和類(lèi)型見(jiàn)“(3)、1”
為了拓展并識(shí)別其他對(duì)象,需要子類(lèi)化并實(shí)現(xiàn)default()方法為其他對(duì)象o返回一個(gè)可序列化的對(duì)象,否則default()方法應(yīng)調(diào)用超類(lèi)實(shí)現(xiàn)(引發(fā)TypeError)
default——應(yīng)是一個(gè)函數(shù),每當(dāng)某個(gè)對(duì)象無(wú)法被序列化時(shí)會(huì)被調(diào)用并傳參該對(duì)象。此函數(shù)應(yīng)返回該對(duì)象的一個(gè)可以被JSON編碼的版本或者引發(fā)一個(gè)TypeError。如果沒(méi)有指定,則會(huì)引發(fā)TypeError
# 可以通過(guò)實(shí)例化JSONEncoder調(diào)用encode(), iterencode()編碼或創(chuàng)建JSONEncoder的子類(lèi),將子類(lèi)傳入dump()或dumps()的cls參數(shù)編碼
其他參數(shù)見(jiàn)dump()函數(shù)
1.1.?default(o)
在子類(lèi)中實(shí)現(xiàn)這種方法使其返回o的可序列化對(duì)象,或者調(diào)用基礎(chǔ)實(shí)現(xiàn)(引發(fā)TypeError)
1.2.?encode(o)
返回Python數(shù)據(jù)結(jié)構(gòu)o數(shù)據(jù)結(jié)構(gòu)的JSON字符串表達(dá)方式
1.3.?iterencode(o)
對(duì)給定對(duì)象o進(jìn)行編碼,返回每個(gè)可用的字符串表達(dá)方式的生成器
2.?JSONDecoder(*, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, strict=True, object_pairs_hook=None)
簡(jiǎn)單的JSON解碼器
# 默認(rèn)解碼執(zhí)行見(jiàn)“(3)、2”
它將'NaN', 'Infinity'和'-Infinity'理解為它們對(duì)應(yīng)的'float'值,這超出了JSON規(guī)范
strict——如果為False(默認(rèn)值為T(mén)rue),則控制字符允許出現(xiàn)在字符串內(nèi)。在此上下文中的控制字符編碼在范圍0——31內(nèi)的字符,包括'\t', '\n', '\r'和'\0'
其他參數(shù)見(jiàn)load()函數(shù)
如果反序列化的數(shù)據(jù)不是有效JSON文檔,則會(huì)引發(fā)JSONDecodeError
2.1.?decode(s)
返回s的Python表示形式
# s是包含JSON文檔的str對(duì)象
如果給定的JSON文檔無(wú)效則引發(fā)JSONDecodeError
3.?raw_decode(s)
從s中解碼出JSON文檔,返回一個(gè)Python表示形式的2元組:(解碼內(nèi)容, JSON文檔在s中結(jié)束位置的序號(hào))
# s是以JSON文檔開(kāi)頭的str對(duì)象
這可用于從一個(gè)末尾可能有無(wú)關(guān)數(shù)據(jù)的字符串解碼JSON文檔
(6)、異常
1.?JSONDecodeError(msg, doc, pos)
擁有以下附加屬性的ValueError子類(lèi):
msg:未格式化的錯(cuò)誤消息
doc:正在解析的JSON文檔
pos:解析失敗的文檔的起始索引
# 也就是解析失敗時(shí)的索引
lineno:與pos相對(duì)應(yīng)的行
colno:與pos相對(duì)應(yīng)的列
# 關(guān)于標(biāo)準(zhǔn)符合性和互操作性見(jiàn)官方文檔