Bahwa contoh Anda tidak valid hanya karena Anda memilih karakter khusus untuk memulai skalar Anda. Jika Anda mengganti *
dengan beberapa karakter non-cadangan lainnya (saya cenderung menggunakan karakter non-ASCII untuk itu karena jarang digunakan sebagai bagian dari beberapa spesifikasi), Anda akan mendapatkan YAML yang legal:
paths:
root: /path/to/root/
patha: ♦root♦ + a
pathb: ♦root♦ + b
pathc: ♦root♦ + c
Ini akan dimuat ke dalam representasi standar untuk pemetaan dalam bahasa yang digunakan parser Anda dan tidak memperluas apa pun secara ajaib.
Untuk melakukan itu gunakan tipe objek default lokal seperti pada program Python berikut:
from __future__ import print_function
import ruamel.yaml as yaml
class Paths:
def __init__(self):
self.d = {}
def __repr__(self):
return repr(self.d).replace('ordereddict', 'Paths')
@staticmethod
def __yaml_in__(loader, data):
result = Paths()
loader.construct_mapping(data, result.d)
return result
@staticmethod
def __yaml_out__(dumper, self):
return dumper.represent_mapping('!Paths', self.d)
def __getitem__(self, key):
res = self.d[key]
return self.expand(res)
def expand(self, res):
try:
before, rest = res.split(u'♦', 1)
kw, rest = rest.split(u'♦ +', 1)
rest = rest.lstrip()
return before + self.d[kw] + self.expand(rest)
except ValueError:
return res
yaml_str = """\
paths: !Paths
root: /path/to/root/
patha: ♦root♦ + a
pathb: ♦root♦ + b
pathc: ♦root♦ + c
"""
loader = yaml.RoundTripLoader
loader.add_constructor('!Paths', Paths.__yaml_in__)
paths = yaml.load(yaml_str, Loader=yaml.RoundTripLoader)['paths']
for k in ['root', 'pathc']:
print(u'{} -> {}'.format(k, paths[k]))
yang akan mencetak:
root -> /path/to/root/
pathc -> /path/to/root/c
Perluasan dilakukan dengan cepat dan menangani definisi bertingkat, tetapi Anda harus berhati-hati agar tidak meminta rekursi tak terbatas.
Dengan menentukan dumper, Anda dapat membuang YAML asli dari data yang dimuat, karena ekspansi on-the-fly:
dumper = yaml.RoundTripDumper
dumper.add_representer(Paths, Paths.__yaml_out__)
print(yaml.dump(paths, Dumper=dumper, allow_unicode=True))
ini akan mengubah urutan kunci pemetaan. Jika itu adalah masalah Anda harus membuat self.d
sebuah CommentedMap
(diimpor dari ruamel.yaml.comments.py
)