目錄
舉例
註釋
鍵值對
字串
整數
浮點數
布林值
日期
陣列
行内表
表数组
首頁 後端開發 Python教學 怎麼用Python解析toml設定檔

怎麼用Python解析toml設定檔

May 21, 2023 am 11:20 AM
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 也對應一個字典。由於缺乏section,我們需要注意到最初的標題,因此它是一個獨立的鍵。

而且還有一點就是 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字元、數字、底線和連字號。

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': '我是一个字符串,"你可以把我引起来"'}
"""
登入後複製

多行字串可以用三個引號括起來,可以包含換行。但是要注意,開頭引號之後的第一個換行會被移除,其他的空格和換行符會被保留。

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”对应的字典键。此外我们还可以将上面两种方式结合起来:

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設定檔的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1663
14
CakePHP 教程
1420
52
Laravel 教程
1315
25
PHP教程
1266
29
C# 教程
1239
24
PHP和Python:解釋了不同的範例 PHP和Python:解釋了不同的範例 Apr 18, 2025 am 12:26 AM

PHP主要是過程式編程,但也支持面向對象編程(OOP);Python支持多種範式,包括OOP、函數式和過程式編程。 PHP適合web開發,Python適用於多種應用,如數據分析和機器學習。

在PHP和Python之間進行選擇:指南 在PHP和Python之間進行選擇:指南 Apr 18, 2025 am 12:24 AM

PHP適合網頁開發和快速原型開發,Python適用於數據科學和機器學習。 1.PHP用於動態網頁開發,語法簡單,適合快速開發。 2.Python語法簡潔,適用於多領域,庫生態系統強大。

PHP和Python:深入了解他們的歷史 PHP和Python:深入了解他們的歷史 Apr 18, 2025 am 12:25 AM

PHP起源於1994年,由RasmusLerdorf開發,最初用於跟踪網站訪問者,逐漸演變為服務器端腳本語言,廣泛應用於網頁開發。 Python由GuidovanRossum於1980年代末開發,1991年首次發布,強調代碼可讀性和簡潔性,適用於科學計算、數據分析等領域。

Python vs. JavaScript:學習曲線和易用性 Python vs. JavaScript:學習曲線和易用性 Apr 16, 2025 am 12:12 AM

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

sublime怎麼運行代碼python sublime怎麼運行代碼python Apr 16, 2025 am 08:48 AM

在 Sublime Text 中運行 Python 代碼,需先安裝 Python 插件,再創建 .py 文件並編寫代碼,最後按 Ctrl B 運行代碼,輸出會在控制台中顯示。

vscode在哪寫代碼 vscode在哪寫代碼 Apr 15, 2025 pm 09:54 PM

在 Visual Studio Code(VSCode)中編寫代碼簡單易行,只需安裝 VSCode、創建項目、選擇語言、創建文件、編寫代碼、保存並運行即可。 VSCode 的優點包括跨平台、免費開源、強大功能、擴展豐富,以及輕量快速。

Golang vs. Python:性能和可伸縮性 Golang vs. Python:性能和可伸縮性 Apr 19, 2025 am 12:18 AM

Golang在性能和可擴展性方面優於Python。 1)Golang的編譯型特性和高效並發模型使其在高並發場景下表現出色。 2)Python作為解釋型語言,執行速度較慢,但通過工具如Cython可優化性能。

visual studio code 可以用於 python 嗎 visual studio code 可以用於 python 嗎 Apr 15, 2025 pm 08:18 PM

VS Code 可用於編寫 Python,並提供許多功能,使其成為開發 Python 應用程序的理想工具。它允許用戶:安裝 Python 擴展,以獲得代碼補全、語法高亮和調試等功能。使用調試器逐步跟踪代碼,查找和修復錯誤。集成 Git,進行版本控制。使用代碼格式化工具,保持代碼一致性。使用 Linting 工具,提前發現潛在問題。

See all articles