Python解析toml配置文件的方法分享
楔子
上一篇文章我們介紹了 yaml,雖然 yaml 的表達(dá)能力已經(jīng)很豐富了,但 GitHub 覺(jué)得還是不夠優(yōu)雅,所以鼓搗出了一個(gè) toml。toml 有著比 yaml 更簡(jiǎn)潔的語(yǔ)法,它的目標(biāo)就是成為一個(gè)最簡(jiǎn)單的配置文件格式。
然后 Python 解析 toml 文件需要使用一個(gè)名字也叫 toml 的庫(kù),直接 pip install toml 即可。
舉個(gè)例子
有了 ini 和 yaml,相信 toml 學(xué)習(xí)來(lái)也很簡(jiǎn)單,先直接看一個(gè)例子吧。
import?toml config?=?""" title?=?"toml?小栗子" [owner] name?=?"古明地覺(jué)" age?=?17 place?=?"東方地靈殿" nickname?=?["小五",?"少女覺(jué)",?"覺(jué)大人"] [database] host?=?"127.0.0.1" port?=?5432 username?=?"satori" password?=?"123456" echo?=?true [server] ????[server.v1] ????api?=?"1.1" ????enable?=?false ???? ????[server.v2] ????api?=?"1.2" ????enable?=?true [client] client?=?[ ????["socket",?"webservice"],? ????[5555] ] address?=?[ ????"xxxx", ????"yyyy" ] """ # loads:從字符串加載 # load:從文件加載 # dumps:生成 toml 格式字符串 # dump:生成 toml 格式字符串并寫(xiě)入文件中 data?=?toml.loads(config) print(data) """ { ????'title':?'toml?小栗子',? ????'owner':?{'name':?'古明地覺(jué)',? ??????????????'age':?17,? ??????????????'place':?'東方地靈殿',? ??????????????'nickname':?['小五',?'少女覺(jué)',?'覺(jué)大人']}, ????'database':?{'host':?'127.0.0.1',? ?????????????????'port':?5432, ?????????????????'username':?'satori',? ?????????????????'password':?'123456',? ?????????????????'echo':?True}, ????'server':?{'v1':?{'api':?'1.1',?'enable':?False},? ???????????????'v2':?{'api':?'1.2',?'enable':?True}}, ????'client':?{'client':?[['socket',?'webservice'],?[5555]],? ???????????????'address':?['xxxx',?'yyyy']} } """
toml 是采用 var = value 的形式進(jìn)行配置,然后也有類(lèi)似于 ini 里面的 section,每個(gè) section 都是字典中的一個(gè) key,然后該 key 也對(duì)應(yīng)一個(gè)字典。但是我們注意看最開(kāi)始的 title,由于它上面沒(méi)有 section,所以它是一個(gè)單獨(dú)的 key。
而且還有一點(diǎn)就是 toml 支持嵌套,我們看到 server.v1,表示 v1 是 server 對(duì)應(yīng)的字典里面的一個(gè) key,然后 v1 對(duì)應(yīng)的值還是一個(gè)字典。
toml 變得更加簡(jiǎn)單了,而且寫(xiě)來(lái)也非常像 Python,它有如下特點(diǎn):
toml 文件是大小寫(xiě)敏感的;
toml 文件必須是有效的 UTF-8 編碼的 Unicode 文檔;
toml 文件的空白符應(yīng)該是 Tab 或者空格;
toml 文件的換行是 LF 或者 CRLF;
然后我們來(lái)介紹一下 toml 的數(shù)據(jù)結(jié)構(gòu)。
注釋
toml 采用 # 表示注釋?zhuān)e個(gè)例子:
#?這是注釋 key?=?"value"??#?也是注釋
可以解析一下看看會(huì)得到什么,劇透:會(huì)得到只包含一個(gè)鍵值對(duì)的字典。
鍵值對(duì)
TOML 文檔最基本的構(gòu)成區(qū)塊是鍵值對(duì),鍵名在等號(hào)的左邊、值在右邊,并且鍵名和鍵值周?chē)目瞻讜?huì)被忽略。此外鍵、等號(hào)和值必須在同一行(不過(guò)有些值可以跨多行)。
key?=?"value"
鍵名可以是裸露的(裸鍵),引號(hào)引起來(lái)的(引號(hào)鍵),或點(diǎn)分隔的(點(diǎn)分隔鍵)。裸鍵只能包含:ascii 字符、ascii 數(shù)字、下劃線、短橫線。
import?toml config?=?""" key?=?"value" bare_key?=?"value" bare-key?=?"value" #?1234?會(huì)被當(dāng)成字符串 1234?=?"value"?? """ data?=?toml.loads(config) print(data) """ {'key':?'value',? ?'bare_key':?'value',? ?'bare-key':?'value',? ?'1234':?'value'} """
如果不是裸鍵,那么就必須使用引號(hào)括起來(lái),但是此時(shí)也支持我們使用更加廣泛的鍵名,但除了特殊場(chǎng)景,否則使用裸鍵是最佳實(shí)踐。
import?toml config?=?""" "127.0.0.1"?=?"value" "character?encoding"?=?"value" "???"?=?"value" 'key2'?=?"value" 'quoted?"value"'?=?"value"? """ data?=?toml.loads(config) print(data) """ {'127.0.0.1':?'value',? ?'character?encoding':?'value',? ?'???':?'value',? ?'key2':?'value',? ?'quoted?"value"':?'value'} """
注意:裸鍵不能為空,但空引號(hào)鍵是允許的(雖然不建議如此)。
=?"沒(méi)有鍵名"??#?錯(cuò)誤 ""?=?"空"?????#?正確但不鼓勵(lì) ''?=?'空'?????#?正確但不鼓勵(lì)
然后是點(diǎn)分隔鍵,它是一系列通過(guò)點(diǎn)相連的裸鍵或引號(hào)鍵,這允許我們將相近屬性放在一起:
import?toml config?=?""" name?=?"橙子" physical.color?=?"橙色" physical.shape?=?"圓形" site."google.com"?=?true site.google.com?=?true a.b.c.d?=?123 """ data?=?toml.loads(config) print(data) """ { ????'name':?'橙子', ????'physical':?{'color':?'橙色', ?????????????????'shape':?'圓形'}, ????'site':?{'google.com':?True, ?????????????'google':?{'com':?True}}, ????'a':?{'b':?{'c':?{'d':?123}}} } """
我們看到這個(gè)點(diǎn)分隔符不錯(cuò)喲,自動(dòng)實(shí)現(xiàn)了嵌套結(jié)構(gòu),并且點(diǎn)分隔符周?chē)目瞻讜?huì)被忽略。
fruit.name?=?"香蕉"?????#?這是最佳實(shí)踐 fruit.?color?=?"黃色"????#?等同于?fruit.color fruit?.?flavor?=?"香蕉"???#?等同于?fruit.flavor
注意:多次定義同一個(gè)鍵是不行的。
import?toml config?=?""" #?name?和?"name"?是等價(jià)的 name?=?"古明地覺(jué)" "name"?=?"古明地戀"?? """ try: ????data?=?toml.loads(config) except?toml.decoder.TomlDecodeError?as?e: ????print(e) """ Duplicate?keys!?(line?4?column?1?char?36) """
對(duì)于點(diǎn)分隔鍵也是如此,只要一個(gè)鍵還沒(méi)有被直接定義過(guò),我們就仍可以對(duì)它和它下屬的鍵名賦值。
import?toml config?=?""" fruit.apple.smooth?=?true#?此時(shí)可以繼續(xù)操作?fruit、fruit.apple,它們都是字典 #?給?fruit?這個(gè)字典加一個(gè)?key?? fruit.orange?=?2?? #?給?fruit.apple?加一個(gè)?key fruit.apple.color?=?"red"??? """ data?=?toml.loads(config) print(data) """ { ????'fruit':?{'apple':?{'smooth':?True,? ????????????????????????'color':?'red'},? ??????????????'orange':?2} } """
但下面這個(gè)操作是不行的:
#?將?fruit.apple?的值定義為一個(gè)整數(shù) fruit.apple?=?1 #?但接下來(lái)就不合法了,因?yàn)檎麛?shù)不能變成字典 fruit.apple.smooth?=?true #?如果我們?cè)O(shè)置?fruit.apple?=?{},那么第二個(gè)賦值是可以的 #?沒(méi)錯(cuò),我們可以通過(guò)?{}?直接創(chuàng)建一個(gè)字典
可以看到,真的很像 Python。然后再來(lái)說(shuō)一個(gè)特例:
import?toml config?=?""" 3.14?=?"pi"?? "3.14"?=?"pi"?? """ data?=?toml.loads(config) print(data) """ {'3':?{'14':?'pi'},?'3.14':?'pi'} """
如果鍵是浮點(diǎn)數(shù),那么需要使用引號(hào)括起來(lái),否則會(huì)被解釋為點(diǎn)分隔鍵。
看完了鍵,再來(lái)看看值(value),其實(shí)對(duì)于 toml 來(lái)說(shuō),值比鍵要簡(jiǎn)單的多得多。
字符串
字符串共有四種方式來(lái)表示:基礎(chǔ)式的,多行基礎(chǔ)式的,字面量式的,和多行字面量式的。
1)基礎(chǔ)字符串由引號(hào)包裹,任何 Unicode 字符都可以使用,除了那些必須轉(zhuǎn)義的。
import?toml config?=?""" str?=?'我是一個(gè)字符串,"你可以把我引起來(lái)"'? """ data?=?toml.loads(config) print(data) """ {'str':?'我是一個(gè)字符串,"你可以把我引起來(lái)"'} """
2)多行字符串由三個(gè)引號(hào)包裹,允許換行,注意:緊隨開(kāi)頭引號(hào)的換行會(huì)被去除,其它空白和換行會(huì)被原樣保留。
import?toml config?=?""" str?=?''' 玫瑰是紅色的 紫羅蘭是藍(lán)色的 ''' """ data?=?toml.loads(config) print(data) """ {'str':?'玫瑰是紅色的\n紫羅蘭是藍(lán)色的\n'} """
這里的引號(hào)可以是雙引號(hào)、也可以是單引號(hào)。
整數(shù)
整數(shù)是純數(shù)字,正數(shù)可以有加號(hào)前綴,負(fù)數(shù)的前綴是減號(hào)。
import?toml config?=?""" int1?=?+99 int2?=?42 int3?=?0 int4?=?-17 #?對(duì)于大數(shù),可以在數(shù)字之間用下劃線來(lái)增強(qiáng)可讀性 #?每個(gè)下劃線兩側(cè)必須至少有一個(gè)數(shù)字。 int5?=?1_000 int6?=?5_349_221 int7?=?53_49_221??#?印度記數(shù)體系分組 int8?=?1_2_3_4_5??#?無(wú)誤但不鼓勵(lì) """ data?=?toml.loads(config) print(data) """ {'int1':?99, ?'int2':?42, ?'int3':?0, ?'int4':?-17, ?'int5':?1000, ?'int6':?5349221, ?'int7':?5349221, ?'int8':?12345} """
但是注意:數(shù)字不能以零開(kāi)頭,除了 0 本身。當(dāng)然 -0 與 +0 也是有效的,并等同于無(wú)前綴的零。非負(fù)整數(shù)值也可以用十六進(jìn)制、八進(jìn)制或二進(jìn)制來(lái)表示。
#?帶有?`0x`?前綴的十六進(jìn)制,大小寫(xiě)均可 hex1?=?0xDEADBEEF hex2?=?0xdeadbeef hex3?=?0xdead_beef #?帶有?`0o`?前綴的八進(jìn)制 oct1?=?0o01234567 oct2?=?0o755?#?對(duì)于表示?Unix?文件權(quán)限很有用 #?帶有?`0b`?前綴的二進(jìn)制 bin1?=?0b11010110
浮點(diǎn)數(shù)
一個(gè)浮點(diǎn)數(shù)由一個(gè)整數(shù)部分(遵從與十進(jìn)制整數(shù)值相同的規(guī)則)后跟上一個(gè)小數(shù)部分、或一個(gè)指數(shù)部分組成。如果小數(shù)部分和指數(shù)部分兼有,那小數(shù)部分必須在指數(shù)部分前面。
import?toml config?=?""" #?小數(shù) flt1?=?+1.0 flt2?=?3.1415 flt3?=?-0.01 #?指數(shù) flt4?=?5e+22 flt5?=?1e06 flt6?=?-2E-2 flt7?=?6.626e-34 """ data?=?toml.loads(config) print(data) """ {'flt1':?1.0, ?'flt2':?3.1415, ?'flt3':?-0.01, ?'flt4':?5e+22, ?'flt5':?1000000.0, ?'flt6':?-0.02, ?'flt7':?6.626e-34} """
小數(shù)部分是一個(gè)小數(shù)點(diǎn)后跟一個(gè)或多個(gè)數(shù)字,一個(gè)指數(shù)部分是一個(gè) E(大小寫(xiě)均可)后跟一個(gè)整數(shù)部分(遵從與十進(jìn)制整數(shù)值相同的規(guī)則,但可以包含前導(dǎo)零)。小數(shù)點(diǎn),如果有用到的話,每側(cè)必須緊鄰至少一個(gè)數(shù)字。
#?非法的浮點(diǎn)數(shù) invalid_float_1?=?.7 invalid_float_2?=?7. invalid_float_3?=?3.e+20
與整數(shù)相似,可以使用下劃線來(lái)增強(qiáng)可讀性,每個(gè)下劃線必須被至少一個(gè)數(shù)字圍繞。
flt8?=?224_617.445_991_228
浮點(diǎn)數(shù)值 -0.0 與 +0.0 是有效的,并且應(yīng)當(dāng)遵從 IEEE 754。特殊浮點(diǎn)值也能夠表示:
#?無(wú)窮 sf1?=?inf??#?正無(wú)窮 sf2?=?+inf?#?正無(wú)窮 sf3?=?-inf?#?負(fù)無(wú)窮 #?非數(shù) sf4?=?nan??#?是對(duì)應(yīng)信號(hào)非數(shù)碼還是靜默非數(shù)碼,取決于實(shí)現(xiàn) sf5?=?+nan?#?等同于?`nan` sf6?=?-nan?#?正確,實(shí)際碼取決于實(shí)現(xiàn)
布爾值
布爾值就是慣用的那樣,但要小寫(xiě)。
bool1?=?true bool2?=?false
日期
可以是普通的 datetime,或者是遵循 ISO-8859-1 格式的日期。
import?toml config?=?""" dt1?=?2020-01-01T12:33:22+00:00 dt2?=?2020-11-12?12:11:33 dt3?=?2020-11-23 """ data?=?toml.loads(config) print(data) """ {'dt1':?datetime.datetime(2020,?1,?1,?12,?33,?22,?tzinfo=...),? ?'dt2':?datetime.datetime(2020,?11,?12,?12,?11,?33),? ?'dt3':?datetime.date(2020,?11,?23)} """
數(shù)組
語(yǔ)法和 Python 的列表類(lèi)似:
import?toml config?=?""" #?每個(gè)數(shù)組里面的元素類(lèi)型要一致 integers?=?[1,?2,?3] colors?=?["紅",?"黃",?"綠"] nested_array_of_ints?=?[[1,?2],?[3,?4,?5]] nested_mixed_array?=?[[1,?2],?["a",?"b",?"c"]] numbers?=?[0.1,?0.2,?0.5] """ data?=?toml.loads(config) print(data) """ {'colors':?['紅',?'黃',?'綠'], ?'integers':?[1,?2,?3], ?'nested_array_of_ints':?[[1,?2],?[3,?4,?5]], ?'nested_mixed_array':?[[1,?2],?['a',?'b',?'c']], ?'numbers':?[0.1,?0.2,?0.5]} """
數(shù)組可以跨行,數(shù)組的最后一個(gè)值后面可以有終逗號(hào)(也稱(chēng)為尾逗號(hào))。
import?toml config?=?""" integers2?=?[ ??1,?2,?3 ] integers3?=?[ ??1, ??2,?#?這是可以的 ] """ data?=?toml.loads(config) print(data) """ {'integers2':?[1,?2,?3],?'integers3':?[1,?2]} """
表
表,完全可以把它想象成 ini 的 section。
import?toml config?=?""" #?表名的定義規(guī)則與鍵名相同 #?解析之后得到的大字典中就有?"table-1"?這個(gè)?key #?并且其?value?也是一個(gè)表,在它下方 #?直至下一個(gè)表頭或文件結(jié)束,都是這個(gè)表內(nèi)部的鍵值對(duì) [table-1] key1?=?"some?string" key2?=?123 [table-2] key1?=?"another?string" key2?=?456 """ data?=?toml.loads(config) print(data) """ {'table-1':?{'key1':?'some?string',?'key2':?123}, ?'table-2':?{'key1':?'another?string',?'key2':?456}} """
但是我們之前也實(shí)現(xiàn)過(guò)類(lèi)似于這種結(jié)構(gòu),沒(méi)錯(cuò),就是點(diǎn)分隔符:
import?toml config?=?""" #?所以?other-table-1?和?table-1?是等價(jià)的 #?other-table-2?和?table-2?是等價(jià)的 other-table-1.key1?=?"some?string" other-table-1.key2?=?123 other-table-2.key1?=?"another?string" other-table-2.key2?=?456 [table-1] key1?=?"some?string" key2?=?123 [table-2] key1?=?"another?string" key2?=?456 """ data?=?toml.loads(config) print(data) """ {'other-table-1':?{'key1':?'some?string',?'key2':?123}, ?'other-table-2':?{'key1':?'another?string',?'key2':?456}, ?'table-1':?{'key1':?'some?string',?'key2':?123}, ?'table-2':?{'key1':?'another?string',?'key2':?456}} """
不過(guò)注意:我們必須要把 other-table-1 和 other-table-2 定義在上面,如果我們定義在下面看看會(huì)有什么后果:
import?toml config?=?""" [table-1] key1?=?"some?string" key2?=?123 [table-2] key1?=?"another?string" key2?=?456 other-table-1.key1?=?"some?string" other-table-1.key2?=?123 other-table-2.key1?=?"another?string" other-table-2.key2?=?456 """ data?=?toml.loads(config) print(data) """ { ????'table-1':?{'key1':?'some?string',?'key2':?123}, ????'table-2':?{'key1':?'another?string', ????????????????'key2':?456, ????????????????'other-table-1':?{'key1':?'some?string',? ??????????????????????????????????'key2':?123}, ????????????????'other-table-2':?{'key1':?'another?string',? ??????????????????????????????????'key2':?456}} } """
估計(jì)你已經(jīng)猜到了,它們被當(dāng)成了 'table-2' 對(duì)應(yīng)的字典里面的 key 了。此外我們還可以將上面兩種方式結(jié)合起來(lái):
import?toml config?=?""" #?[]?里面的不再是一個(gè)普通的鍵,而是點(diǎn)分隔鍵 #?另外鍵名周?chē)目崭駮?huì)被忽略,但是最好不要有 [dog??.??"tater.man"]?? type.name?=?"哈巴狗" """ data?=?toml.loads(config) print(data) """ { ????'dog':?{'tater.man':?{'type':?{'name':?'哈巴狗'}}} } """
表的里面也是可以沒(méi)有鍵值對(duì)的:
import?toml config?=?""" [x.y.z.w.a.n] [x.m] [x.n] [x] a.b.c?=?"xxx" """ data?=?toml.loads(config) print(data) """ {'x': ????{ ????????'a':?{'b':?{'c':?'xxx'}}, ????????'m':?{}, ????????'n':?{}, ????????'y':?{'z':?{'w':?{'a':?{'n':?{}}}}} ????} } """
總的來(lái)說(shuō)還是蠻強(qiáng)大的,但是要注意:不能重復(fù)定義。
行內(nèi)表
行內(nèi)表提供了一種更為緊湊的語(yǔ)法來(lái)表示表,因?yàn)樯厦婷恳粋€(gè)鍵值對(duì)都需要單獨(dú)寫(xiě)一行,比如:
[table1] a?=?1 b?=?2 c?=?3 #?最終可以得到? #?{'table1':?{'a':?1,?'b':?2,?'c':?3}}
但是除了上面的表達(dá)方式之外,我們還可以采用行內(nèi)表:
import?toml config?=?""" #?和?Python?字典的表示方式略有不同 #?并且也支持多種?key table1?=?{a?=?1,?b?=?"二",?c.a?=?"3"} table2?=?{c."b?c".d?=?"4"} """ data?=?toml.loads(config) print(data) """ { ????'table1':?{'a':?1,?'b':?'二',?'c':?{'a':?'3'}}, ????'table2':?{'c':?{'b?c':?{'d':?'4'}}} } """
表數(shù)組
然后來(lái)看看數(shù)組和表的結(jié)合:
import?toml config?=?""" [name1] girl?=?"古明地覺(jué)" [[name2]] girl?=?"古明地戀" [name3] [[name4]] """ data?=?toml.loads(config) print(data) """ {'name1':?{'girl':?'古明地覺(jué)'}, ?'name2':?[{'girl':?'古明地戀'}], ?'name3':?{}, ?'name4':?[{}]} """
當(dāng)使用 [[]] 的時(shí)候,相當(dāng)于在 [] 的基礎(chǔ)上套上一層列表。并且任何對(duì)表數(shù)組的引用都指向該數(shù)組里最近定義的表元素,這允許我們?cè)谧罱谋韮?nèi)定義子表,甚至子表數(shù)組。
我們?cè)倥e個(gè)更復(fù)雜的例子:
import?toml config?=?""" [[fruits]]?? name?=?"蘋(píng)果"?? #?會(huì)操作?[]?里面最近定義的?{} [fruits.physical]?? color?=?"紅色" shape?=?"圓形" [[fruits.varieties]]??#?嵌套表數(shù)組 name?=?"蛇果"???? [[fruits.varieties]] name?=?"澳洲青蘋(píng)"? [[fruits]] name?=?"香蕉"? [[fruits.varieties]] name?=?"車(chē)前草"?? """ data?=?toml.loads(config) print(data) """ { ????'fruits': ????????[ ????????????{ ????????????????'name':?'蘋(píng)果', ????????????????'physical':?{'color':?'紅色',? ?????????????????????????????'shape':?'圓形'}, ????????????????'varieties':?[{'name':?'蛇果'},? ??????????????????????????????{'name':?'澳洲青蘋(píng)'}] ????????????}, ????????????{ ????????????????'name':?'香蕉',? ????????????????'varieties':?[{'name':?'車(chē)前草'}] ????????????} ????????] } """
很明顯這種定義不是很常用,配置文件應(yīng)該要非常直觀才對(duì),但這已經(jīng)不是很好理解了。
以上就是Python解析toml配置文件的方法分享的詳細(xì)內(nèi)容,更多關(guān)于Python解析toml的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Python urlencode和unquote函數(shù)使用實(shí)例解析
這篇文章主要介紹了Python urlencode和unquote函數(shù)使用實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03Python Django框架url反向解析實(shí)現(xiàn)動(dòng)態(tài)生成對(duì)應(yīng)的url鏈接示例
這篇文章主要介紹了Python Django框架url反向解析實(shí)現(xiàn)動(dòng)態(tài)生成對(duì)應(yīng)的url鏈接,結(jié)合實(shí)例形式分析了Django框架URL反向解析具體原理與應(yīng)用操作技巧,需要的朋友可以參考下2019-10-10使用PIL(Python-Imaging)反轉(zhuǎn)圖像的顏色方法
今天小編就為大家分享一篇使用PIL(Python-Imaging)反轉(zhuǎn)圖像的顏色方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-01-01通過(guò)gradio和攝像頭獲取照片和視頻實(shí)現(xiàn)過(guò)程
這篇文章主要為大家介紹了gradio和攝像頭獲取照片和視頻實(shí)現(xiàn)過(guò)程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04用Python的Flask框架結(jié)合MySQL寫(xiě)一個(gè)內(nèi)存監(jiān)控程序
這篇文章主要介紹了用Python的Flask框架結(jié)合MySQL些一個(gè)內(nèi)存監(jiān)控程序的例子,并且能將結(jié)果作簡(jiǎn)單的圖形化顯示,需要的朋友可以參考下2015-11-11解決新版Pycharm中Matplotlib圖像不在彈出獨(dú)立的顯示窗口問(wèn)題
今天小編就為大家分享一篇解決新版Pycharm中Matplotlib圖像不在彈出獨(dú)立的顯示窗口問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-01-01