中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么用Python解析toml配置文件

發布時間:2022-09-19 14:13:00 來源:億速云 閱讀:284 作者:iii 欄目:開發技術

本篇內容介紹了“怎么用Python解析toml配置文件”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

舉個例子

有了 ini 和 yaml,相信 toml 學習來也很簡單,先直接看一個例子吧。

import toml

config = """
title = "toml 小栗子"

[owner]
name = "古明地覺"
age = 17
place = "東方地靈殿"
nickname = ["小五", "少女覺", "覺大人"]

[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 格式字符串并寫入文件中
data = toml.loads(config)
print(data)
"""
{
    'title': 'toml 小栗子', 
    'owner': {'name': '古明地覺', 
              'age': 17, 
              'place': '東方地靈殿', 
              'nickname': ['小五', '少女覺', '覺大人']},
    '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 的形式進行配置,然后也有類似于 ini 里面的 section,每個 section 都是字典中的一個 key,然后該 key 也對應一個字典。但是我們注意看最開始的 title,由于它上面沒有 section,所以它是一個單獨的 key。

而且還有一點就是 toml 支持嵌套,我們看到 server.v1,表示 v1 是 server 對應的字典里面的一個 key,然后 v1 對應的值還是一個字典。

toml 變得更加簡單了,而且寫來也非常像 Python,它有如下特點:

toml 文件是大小寫敏感的;

toml 文件必須是有效的 UTF-8 編碼的 Unicode 文檔;

toml 文件的空白符應該是 Tab 或者空格;

toml 文件的換行是 LF 或者 CRLF;

然后我們來介紹一下 toml 的數據結構。

注釋

toml 采用 # 表示注釋,舉個例子:

# 這是注釋
key = "value"  # 也是注釋

可以解析一下看看會得到什么,劇透:會得到只包含一個鍵值對的字典。

鍵值對

TOML 文檔最基本的構成區塊是鍵值對,鍵名在等號的左邊、值在右邊,并且鍵名和鍵值周圍的空白會被忽略。此外鍵、等號和值必須在同一行(不過有些值可以跨多行)。

key = "value"

鍵名可以是裸露的(裸鍵),引號引起來的(引號鍵),或點分隔的(點分隔鍵)。裸鍵只能包含:ascii 字符、ascii 數字、下劃線、短橫線。

import toml

config = """
key = "value"
bare_key = "value"
bare-key = "value"
# 1234 會被當成字符串
1234 = "value"  
"""

data = toml.loads(config)
print(data)
"""
{'key': 'value', 
 'bare_key': 'value', 
 'bare-key': 'value', 
 '1234': 'value'}
"""

如果不是裸鍵,那么就必須使用引號括起來,但是此時也支持我們使用更加廣泛的鍵名,但除了特殊場景,否則使用裸鍵是最佳實踐。

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

注意:裸鍵不能為空,但空引號鍵是允許的(雖然不建議如此)。

= "沒有鍵名"  # 錯誤
"" = "空"     # 正確但不鼓勵
'' = '空'     # 正確但不鼓勵

然后是點分隔鍵,它是一系列通過點相連的裸鍵或引號鍵,這允許我們將相近屬性放在一起:

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

我們看到這個點分隔符不錯喲,自動實現了嵌套結構,并且點分隔符周圍的空白會被忽略。

fruit.name = "香蕉"     # 這是最佳實踐
fruit. color = "黃色"    # 等同于 fruit.color
fruit . flavor = "香蕉"   # 等同于 fruit.flavor

注意:多次定義同一個鍵是不行的。

import toml

config = """
# name 和 "name" 是等價的
name = "古明地覺"
"name" = "古明地戀"  
"""

try:
    data = toml.loads(config)
except toml.decoder.TomlDecodeError as e:
    print(e)
"""
Duplicate keys! (line 4 column 1 char 36)
"""

對于點分隔鍵也是如此,只要一個鍵還沒有被直接定義過,我們就仍可以對它和它下屬的鍵名賦值。

import toml

config = """
fruit.apple.smooth = true# 此時可以繼續操作 fruit、fruit.apple,它們都是字典
# 給 fruit 這個字典加一個 key  
fruit.orange = 2  
# 給 fruit.apple 加一個 key
fruit.apple.color = "red"   
"""

data = toml.loads(config)
print(data)
"""
{
    'fruit': {'apple': {'smooth': True, 
                        'color': 'red'}, 
              'orange': 2}
}
"""

但下面這個操作是不行的:

# 將 fruit.apple 的值定義為一個整數
fruit.apple = 1
# 但接下來就不合法了,因為整數不能變成字典
fruit.apple.smooth = true

# 如果我們設置 fruit.apple = {},那么第二個賦值是可以的
# 沒錯,我們可以通過 {} 直接創建一個字典

可以看到,真的很像 Python。然后再來說一個特例:

import toml

config = """
3.14 = "pi"  
"3.14" = "pi"  
"""

data = toml.loads(config)
print(data)
"""
{'3': {'14': 'pi'}, '3.14': 'pi'}
"""

如果鍵是浮點數,那么需要使用引號括起來,否則會被解釋為點分隔鍵。

看完了鍵,再來看看值(value),其實對于 toml 來說,值比鍵要簡單的多得多。

字符串

字符串共有四種方式來表示:基礎式的,多行基礎式的,字面量式的,和多行字面量式的。

1)基礎字符串由引號包裹,任何 Unicode 字符都可以使用,除了那些必須轉義的。

import toml

config = """
str = '我是一個字符串,"你可以把我引起來"' 
"""

data = toml.loads(config)
print(data)
"""
{'str': '我是一個字符串,"你可以把我引起來"'}
"""

2)多行字符串由三個引號包裹,允許換行,注意:緊隨開頭引號的換行會被去除,其它空白和換行會被原樣保留。

import toml

config = """
str = '''
玫瑰是紅色的
紫羅蘭是藍色的
'''
"""

data = toml.loads(config)
print(data)
"""
{'str': '玫瑰是紅色的\n紫羅蘭是藍色的\n'}
"""

這里的引號可以是雙引號、也可以是單引號。

整數

整數是純數字,正數可以有加號前綴,負數的前綴是減號。

import toml

config = """
int1 = +99
int2 = 42
int3 = 0
int4 = -17

# 對于大數,可以在數字之間用下劃線來增強可讀性
# 每個下劃線兩側必須至少有一個數字。
int5 = 1_000
int6 = 5_349_221
int7 = 53_49_221  # 印度記數體系分組
int8 = 1_2_3_4_5  # 無誤但不鼓勵
"""

data = toml.loads(config)
print(data)
"""
{'int1': 99,
 'int2': 42,
 'int3': 0,
 'int4': -17,
 'int5': 1000,
 'int6': 5349221,
 'int7': 5349221,
 'int8': 12345}
"""

但是注意:數字不能以零開頭,除了 0 本身。當然 -0 與 +0 也是有效的,并等同于無前綴的零。非負整數值也可以用十六進制、八進制或二進制來表示。

# 帶有 `0x` 前綴的十六進制,大小寫均可
hex1 = 0xDEADBEEF
hex2 = 0xdeadbeef
hex3 = 0xdead_beef

# 帶有 `0o` 前綴的八進制
oct1 = 0o01234567
oct2 = 0o755 # 對于表示 Unix 文件權限很有用

# 帶有 `0b` 前綴的二進制
bin1 = 0b11010110

浮點數

一個浮點數由一個整數部分(遵從與十進制整數值相同的規則)后跟上一個小數部分、或一個指數部分組成。如果小數部分和指數部分兼有,那小數部分必須在指數部分前面。

import toml

config = """
# 小數
flt1 = +1.0
flt2 = 3.1415
flt3 = -0.01

# 指數
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}
"""

小數部分是一個小數點后跟一個或多個數字,一個指數部分是一個 E(大小寫均可)后跟一個整數部分(遵從與十進制整數值相同的規則,但可以包含前導零)。小數點,如果有用到的話,每側必須緊鄰至少一個數字。

# 非法的浮點數
invalid_float_1 = .7
invalid_float_2 = 7.
invalid_float_3 = 3.e+20

與整數相似,可以使用下劃線來增強可讀性,每個下劃線必須被至少一個數字圍繞。

flt8 = 224_617.445_991_228

浮點數值 -0.0 與 +0.0 是有效的,并且應當遵從 IEEE 754。特殊浮點值也能夠表示:

# 無窮
sf1 = inf  # 正無窮
sf2 = +inf # 正無窮
sf3 = -inf # 負無窮

# 非數
sf4 = nan  # 是對應信號非數碼還是靜默非數碼,取決于實現
sf5 = +nan # 等同于 `nan`
sf6 = -nan # 正確,實際碼取決于實現

布爾值

布爾值就是慣用的那樣,但要小寫。

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

數組

語法和 Python 的列表類似:

import toml

config = """
# 每個數組里面的元素類型要一致
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]}
"""

數組可以跨行,數組的最后一個值后面可以有終逗號(也稱為尾逗號)。

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 = """
# 表名的定義規則與鍵名相同
# 解析之后得到的大字典中就有 "table-1" 這個 key
# 并且其 value 也是一個表,在它下方
# 直至下一個表頭或文件結束,都是這個表內部的鍵值對
[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}}
"""

但是我們之前也實現過類似于這種結構,沒錯,就是點分隔符:

import toml

config = """
# 所以 other-table-1 和 table-1 是等價的
# other-table-2 和 table-2 是等價的
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}}
"""

不過注意:我們必須要把 other-table-1 和 other-table-2 定義在上面,如果我們定義在下面看看會有什么后果:

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

估計你已經猜到了,它們被當成了 'table-2' 對應的字典里面的 key 了。此外我們還可以將上面兩種方式結合起來:

import toml

config = """
# [] 里面的不再是一個普通的鍵,而是點分隔鍵
# 另外鍵名周圍的空格會被忽略,但是最好不要有
[dog  .  "tater.man"]  
type.name = "哈巴狗"
"""

data = toml.loads(config)
print(data)
"""
{
    'dog': {'tater.man': {'type': {'name': '哈巴狗'}}}
}
"""

表的里面也是可以沒有鍵值對的:

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': {}}}}}
    }
}
"""

總的來說還是蠻強大的,但是要注意:不能重復定義。

行內表

行內表提供了一種更為緊湊的語法來表示表,因為上面每一個鍵值對都需要單獨寫一行,比如:

[table1]
a = 1
b = 2
c = 3
# 最終可以得到 
# {'table1': {'a': 1, 'b': 2, 'c': 3}}

但是除了上面的表達方式之外,我們還可以采用行內表:

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

表數組

然后來看看數組和表的結合:

import toml

config = """
[name1]
girl = "古明地覺"

[[name2]]
girl = "古明地戀"

[name3]
[[name4]]
"""

data = toml.loads(config)
print(data)
"""
{'name1': {'girl': '古明地覺'},
 'name2': [{'girl': '古明地戀'}],
 'name3': {},
 'name4': [{}]}
"""

當使用 [[]] 的時候,相當于在 [] 的基礎上套上一層列表。并且任何對表數組的引用都指向該數組里最近定義的表元素,這允許我們在最近的表內定義子表,甚至子表數組。

我們再舉個更復雜的例子:

import toml

config = """
[[fruits]]  
name = "蘋果"  

# 會操作 [] 里面最近定義的 {}
[fruits.physical]  
color = "紅色"
shape = "圓形"

[[fruits.varieties]]  # 嵌套表數組
name = "蛇果"    

[[fruits.varieties]]
name = "澳洲青蘋" 

[[fruits]]
name = "香蕉" 

[[fruits.varieties]]
name = "車前草"  
"""

data = toml.loads(config)
print(data)
"""
{
    'fruits':
        [
            {
                'name': '蘋果',
                'physical': {'color': '紅色', 
                             'shape': '圓形'},
                'varieties': [{'name': '蛇果'}, 
                              {'name': '澳洲青蘋'}]
            },
            {
                'name': '香蕉', 
                'varieties': [{'name': '車前草'}]
            }
        ]
}
"""

很明顯這種定義不是很常用,配置文件應該要非常直觀才對,但這已經不是很好理解了。

“怎么用Python解析toml配置文件”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

盱眙县| 丽江市| 高碑店市| 新竹县| 台北县| 白玉县| 夏河县| 池州市| 龙里县| 阜城县| 天等县| 东乌| 三门峡市| 永顺县| 天峨县| 偃师市| 汶上县| 贡嘎县| 寻甸| 浪卡子县| 建阳市| 泰宁县| 科尔| 武平县| 唐山市| 海原县| 平利县| 绍兴市| 织金县| 抚顺县| 罗平县| 吴江市| 砚山县| 且末县| 虹口区| 罗山县| 海原县| 宁强县| 庐江县| 保山市| 涿鹿县|