Rumah > Artikel > pembangunan bahagian belakang > Cara menggunakan Python untuk menghuraikan fail konfigurasi toml
Dengan ini dan yaml, saya percaya sangat mudah untuk belajar toml Mari kita lihat contoh dahulu.
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 dikonfigurasikan dalam bentuk var = nilai, dan terdapat juga bahagian yang serupa dengan ini Setiap bahagian adalah kunci dalam kamus, dan kunci itu juga sepadan dengan kamus. Oleh kerana kekurangan bahagian, kita perlu perhatikan tajuk awal, jadi ia adalah kunci yang berasingan.
Perkara lain ialah toml menyokong nesting Kami melihat server.v1, yang bermaksud v1 ialah kunci dalam kamus yang sepadan dengan pelayan, dan nilai yang sepadan dengan v1 masih merupakan kamus.
toml telah menjadi lebih mudah, dan ia ditulis seperti Python Ia mempunyai ciri-ciri berikut:
fail toml sensitif huruf besar/kecil
fail toml mestilah Sah Dokumen Unicode yang dikodkan UTF-8;
Watak ruang putih bagi fail toml hendaklah Tab atau ruang;
Pemutus baris fail toml hendaklah LF atau CRLF;
Kemudian kita Mari perkenalkan struktur data toml.
toml menggunakan # untuk mewakili ulasan Contohnya:
# 这是注释 key = "value" # 也是注释
Anda boleh menghuraikannya untuk melihat apa yang anda akan dapat: anda akan mendapat hanya satu kunci-. kamus pasangan nilai.
Blok asas ialah pasangan nilai kunci, dengan nama kunci di sebelah kiri tanda sama dan nilai di sebelah kanan, sambil mengabaikan warna putih ruang di sekeliling nama kunci dan dokumen TOML nilai kunci. Di samping itu, kunci, tanda sama dan nilai mesti berada pada baris yang sama (walaupun beberapa nilai boleh menjangkau beberapa baris).
key = "value"
Nama kunci boleh muncul sebagai kekunci kosong, kekunci petikan atau kekunci dipisahkan titik. Kekunci kosong hanya dibenarkan mengandungi aksara ASCII, nombor, garis bawah dan sempang.
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'} """
Jika ia bukan kunci kosong, ia mesti disertakan dalam tanda petikan, tetapi pada masa ini kami juga menyokong kami untuk menggunakan julat nama kunci yang lebih luas, tetapi kecuali untuk senario khas, menggunakan kekunci kosong adalah amalan terbaik.
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'} """
Nota: Kekunci kosong tidak boleh kosong, tetapi kekunci petikan kosong dibenarkan (walaupun tidak disyorkan).
= "没有键名" # 错误 "" = "空" # 正确但不鼓励 '' = '空' # 正确但不鼓励
Kemudian terdapat kekunci yang dipisahkan dengan titik, yang merupakan satu siri kekunci kosong atau petikan yang disambungkan dengan titik Ini membolehkan kami menggabungkan sifat yang serupa:
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}}} } """
Kami melihat dipisahkan titik ini. kekunci Watak adalah baik, struktur bersarang dilaksanakan secara automatik, dan ruang putih di sekeliling pemisah titik akan diabaikan.
fruit.name = "香蕉" # 这是最佳实践 fruit. color = "黄色" # 等同于 fruit.color fruit . flavor = "香蕉" # 等同于 fruit.flavor
Nota: Tidak mungkin untuk mentakrifkan kunci yang sama beberapa kali.
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) """
Begitu juga dengan kunci yang dipisahkan dengan titik selagi kunci belum ditakrifkan secara langsung, kami masih boleh menetapkan nilai padanya dan nama kunci bawahannya.
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} } """
Tetapi operasi berikut tidak boleh dilakukan:
# 将 fruit.apple 的值定义为一个整数 fruit.apple = 1 # 但接下来就不合法了,因为整数不能变成字典 fruit.apple.smooth = true # 如果我们设置 fruit.apple = {},那么第二个赋值是可以的 # 没错,我们可以通过 {} 直接创建一个字典
Seperti yang anda lihat, ia benar-benar seperti Python. Kemudian mari kita bincangkan tentang kes khas:
import toml config = """ 3.14 = "pi" "3.14" = "pi" """ data = toml.loads(config) print(data) """ {'3': {'14': 'pi'}, '3.14': 'pi'} """
Jika kunci ialah nombor titik terapung, ia perlu disertakan dalam petikan, jika tidak, ia akan ditafsirkan sebagai kunci yang dibatasi titik.
Selepas melihat kekunci, mari kita lihat nilai Sebenarnya, untuk toml, nilai jauh lebih mudah daripada kunci.
Terdapat empat cara untuk mewakili rentetan: asas, berbilang baris asas, tersurat dan berbilang baris tersurat.
1) Rentetan asas dibalut dengan petikan dan sebarang aksara Unicode boleh digunakan, kecuali aksara yang mesti dilepaskan.
import toml config = """ str = '我是一个字符串,"你可以把我引起来"' """ data = toml.loads(config) print(data) """ {'str': '我是一个字符串,"你可以把我引起来"'} """
Rentetan berbilang baris boleh disertakan dalam tiga petikan dan boleh mengandungi baris baharu. Walau bagaimanapun, perlu diingatkan bahawa baris baharu pertama selepas tanda petikan pembukaan akan dialih keluar, dan ruang dan baris baharu lain akan dikekalkan.
import toml config = """ str = ''' 玫瑰是红色的 紫罗兰是蓝色的 ''' """ data = toml.loads(config) print(data) """ {'str': '玫瑰是红色的\n紫罗兰是蓝色的\n'} """
Tanda petikan di sini boleh menjadi tanda petikan berganda atau tanda petikan tunggal.
Integer ialah nombor tulen boleh diawali dengan tanda tambah dan nombor negatif boleh diawali dengan tanda tolak.
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} """
Tetapi ambil perhatian: Nombor tidak boleh bermula dengan sifar, kecuali 0 itu sendiri. Sifar tidak tetap, -0 dan +0 adalah setara. Nilai integer bukan negatif juga boleh diwakili dalam perenambelasan, perlapanan, atau perduaan.
# 带有 `0x` 前缀的十六进制,大小写均可 hex1 = 0xDEADBEEF hex2 = 0xdeadbeef hex3 = 0xdead_beef # 带有 `0o` 前缀的八进制 oct1 = 0o01234567 oct2 = 0o755 # 对于表示 Unix 文件权限很有用 # 带有 `0b` 前缀的二进制 bin1 = 0b11010110
Nombor titik terapung boleh terdiri daripada bahagian integer dan bahagian perpuluhan, atau ia juga boleh terdiri daripada bahagian eksponen. Bahagian integer dan pecahan mengikut peraturan yang sama seperti untuk nilai integer perpuluhan. Jika terdapat kedua-dua bahagian perpuluhan dan bahagian eksponen, bahagian perpuluhan mesti datang sebelum bahagian eksponen.
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} """
Bahagian perpuluhan ialah titik perpuluhan diikuti oleh satu atau lebih digit, bahagian eksponen ialah E (sama ada huruf besar atau kecil) diikuti oleh bahagian integer (mengikut peraturan yang sama seperti nilai integer perpuluhan, tetapi boleh mengandungi sifar pendahuluan ). Titik perpuluhan, jika digunakan, mestilah bersebelahan dengan sekurang-kurangnya satu digit pada setiap sisi.
# 非法的浮点数 invalid_float_1 = .7 invalid_float_2 = 7. invalid_float_3 = 3.e+20
Sama seperti integer, garis bawah boleh digunakan untuk meningkatkan kebolehbacaan Setiap garis bawah mesti dikelilingi oleh sekurang-kurangnya satu digit.
flt8 = 224_617.445_991_228
Nilai titik terapung -0.0 dan +0.0 adalah sah dan harus mematuhi IEEE 754. Nilai titik terapung khas juga boleh diwakili:
# 无穷 sf1 = inf # 正无穷 sf2 = +inf # 正无穷 sf3 = -inf # 负无穷 # 非数 sf4 = nan # 是对应信号非数码还是静默非数码,取决于实现 sf5 = +nan # 等同于 `nan` sf6 = -nan # 正确,实际码取决于实现
Nilai Boolean adalah seperti itu, tetapi dalam huruf kecil.
bool1 = true bool2 = false
boleh menjadi tarikh tarikh biasa, atau tarikh mengikut format 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)} """
Sintaks adalah serupa dengan senarai 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]} """
Arrays boleh menjangkau baris, dan boleh ada koma terminal (juga dipanggil koma trailing) selepas nilai terakhir tatasusunan.
import toml config = """ integers2 = [ 1, 2, 3 ] integers3 = [ 1, 2, # 这是可以的 ] """ data = toml.loads(config) print(data) """ {'integers2': [1, 2, 3], 'integers3': [1, 2]} """
jadual boleh dibayangkan sebagai bahagian ini.
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}} """
Tetapi kami telah melaksanakan struktur yang serupa dengan ini sebelum ini, ya, ia adalah pemisah titik:
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': '车前草'}] } ] } """
很明显这种定义不是很常用,配置文件应该要非常直观才对,但这已经不是很好理解了。
Atas ialah kandungan terperinci Cara menggunakan Python untuk menghuraikan fail konfigurasi toml. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!