J'ai ceci:
user_dir: /home/user
user_pics: /home/user/pics
Comment pourrais-je utiliser le user_dir
pour user_pics? Si je dois spécifier d'autres propriétés comme celle-ci, ce ne serait pas très SEC.
Vous pouvez utiliser un nœud répété, comme ceci:
user_dir: &user_home /home/user
user_pics: *user_home
Je ne pense pas que vous puissiez concaténer, alors cela ne serait pas fonctionne:
user_dir: &user_home /home/user
user_pics: *user_home/pics
Il est surprenant, car le but des ancres et références YAML est de factoriser la duplication des fichiers de données YAML, qu'il n'y a pas de méthode intégrée pour concaténer des chaînes à l'aide de références. Votre cas d'utilisation de la création d'un nom de chemin à partir de pièces est un bon exemple - il doit y avoir de nombreuses utilisations de ce type.
Heureusement, il existe un moyen simple d'ajouter la concaténation de chaînes à YAML via des balises personnalisées en 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]
""")
Ce qui se traduit par:
{'user_dir': '/home/user', 'user_pics': '/home/user/pics'}
Vous pouvez ajouter d'autres éléments au tableau, comme " "
ou "-"
, si les chaînes doivent être délimitées.
Si vous utilisez python avec PyYaml, la jonction de chaînes est possible dans le fichier YAML. Malheureusement, ce n'est qu'une solution python, pas universelle):
avec os.path.join
:
user_dir: &home /home/user
user_pics: !!python/object/apply:os.path.join [*home, pics]
avec string.join
(par souci d'exhaustivité - cette méthode a la flexibilité d'être utilisée pour plusieurs formes de jonction de chaînes:
user_dir: &home /home/user
user_pics: !!python/object/apply:string.join [[*home, pics], /]
Je voudrais utiliser un tableau, puis joindre la chaîne avec le symbole de séparation du système d'exploitation actuel
comme ça:
default: &default_path "you should not use paths in config"
pictures:
- *default_path
- pics
Il me semble que YAML lui-même ne définit pas la façon de le faire .
La bonne nouvelle est que le consommateur YAML pourrait comprendre les variables.
À quoi servira votre YAML?
string.join()
ne fonctionnera pas en Python3, mais vous pouvez définir un !join
comme ça:
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)
En août 2019 :
Pour que la solution Chris ' fonctionne, vous devez en fait ajouter Loader=yaml.Loader
À yaml.load()
. Finalement, le code ressemblerait à ceci:
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]
""", Loader=yaml.Loader)
Voir ce problème GitHub pour plus de détails.