У меня есть это:
user_dir: /home/user
user_pics: /home/user/pics
Как я могу использовать user_dir
для user_pics? Если мне нужно указать другие свойства, подобные этому, это будет не очень СУХОЙ.
У меня есть это:
user_dir: /home/user
user_pics: /home/user/pics
Как я могу использовать user_dir
для user_pics? Если мне нужно указать другие свойства, подобные этому, это будет не очень СУХОЙ.
Вы можете использовать повторяющийся node, например:
user_dir: &user_home /home/user
user_pics: *user_home
Я не думаю, что вы можете конкатенировать, так что это не будет работать:
user_dir: &user_home /home/user
user_pics: *user_home/pics
Удивительно, поскольку цель якорей и ссылок YAML состоит в том, чтобы выделить дубликаты из файлов данных YAML, что нет встроенного способа объединения строк с использованием ссылок. Ваш пример использования построения пути по частям является хорошим примером - таких случаев должно быть много.
К счастью, есть простой способ добавить конкатенацию строк в YAML с помощью пользовательских тегов в Python.
import yaml
## define custom tag handler
def join(loader, node):
seq = loader.construct_sequence(node)
return ''.join([str(i) for i in seq])
## register the tag handler
yaml.add_constructor('!join', join)
## using your sample data
yaml.load("""
user_dir: &DIR /home/user
user_pics: !join [*DIR, /pics]
""")
Что приводит к:
{'user_dir': '/home/user', 'user_pics': '/home/user/pics'}
Вы можете добавить больше элементов в массив, например " "
или "-"
, если строки должны быть разделены.
Если вы используете python с PyYaml, объединение строк возможно в файле YAML. К сожалению, это только решение python, а не универсальное:
с os.path.join
:
user_dir: &home /home/user
user_pics: !!python/object/apply:os.path.join [*home, pics]
с string.join
(для полноты - этот метод имеет гибкость, которую можно использовать для нескольких форм объединения строк:
user_dir: &home /home/user
user_pics: !!python/object/apply:string.join [[*home, pics], /]
Я бы использовал массив, затем присоединил строку вместе с текущим символом разделителя OS
вот так:
default: &default_path "you should not use paths in config"
pictures:
- *default_path
- pics
Мне кажется, что сам YAML не определяет способ сделать это.
Хорошая новость заключается в том, что потребитель YAML может понимать переменные.
Что будет использовать ваш YAML?
string.join()
не будет работать в Python3, но вы можете определить !join
следующим образом:
import functools
import yaml
class StringConcatinator(yaml.YAMLObject):
yaml_loader = yaml.SafeLoader
yaml_tag = '!join'
@classmethod
def from_yaml(cls, loader, node):
return functools.reduce(lambda a, b: a.value + b.value, node.value)
c=yaml.safe_load('''
user_dir: &user_dir /home/user
user_pics: !join [*user_dir, /pics]''')
print(c)