62 votes

Comment faire de la concaténation ou du remplacement de chaînes de caractères dans YAML ?

J'ai ceci :

user_dir: /home/user
user_pics: /home/user/pics

Comment puis-je utiliser le user_dir pour user_pics ? Si je dois spécifier d'autres propriétés de ce type, ce ne sera pas très pratique.

55voto

Brian Wells Points 564

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 l'on puisse concaténer, donc ceci n'aurait pas travail :

user_dir: &user_home /home/user
user_pics: *user_home/pics

3 votes

Merci d'avoir éclairci ce point. J'ai été bien bête de penser que c'était possible.

6 votes

Je ne comprends pas quel est l'intérêt de ces pointeurs si on ne peut pas les utiliser pour concaténer :/

0 votes

Le présent répondre montre comment définir !join pour pouvoir concaténer.

43voto

Chris Johnson Points 2887

Il est surprenant, puisque l'objectif des ancres et des références YAML est d'éliminer la duplication des fichiers de données YAML, qu'il n'y ait pas de moyen intégré de concaténer des chaînes de caractères à l'aide de références. Votre cas d'utilisation de la construction d'un nom de chemin à partir de parties 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.

## in your python code

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 par exemple " " o "-" si les chaînes doivent être délimitées.

10voto

user2502636 Points 117

Si vous utilisez python avec PyYaml, il est possible de joindre des chaînes de caractères dans le fichier YAML. Malheureusement, il ne s'agit que d'une solution python, et non d'une solution universelle :

con os.path.join :

user_dir: &home /home/user
user_pics: !!python/object/apply:os.path.join [*home, pics]

con string.join (par souci d'exhaustivité, cette méthode peut ê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], /]

5 votes

Soyez clair sur la signification de cette approche : vous permettez à l'analyseur Pyyaml d'exécuter du code Python arbitraire à partir du fichier d'entrée yaml. C'est un problème de sécurité extrêmement dangereux si vous ne contrôlez pas la source de l'entrée. De nombreux programmes utiliseront la méthode yaml.safe_load() pour éviter le problème de sécurité. Dans ce cas, votre code ne fonctionnera pas.

0 votes

Avez-vous un exemple en python3 pour la jonction de chaînes de caractères ? cannot find module 'str' (No module named 'str')

7voto

Adam Points 81

J'utiliserais un tableau, puis je joindrais la chaîne à l'aide du symbole de séparation du système d'exploitation actuel.

comme ceci :

default: &default_path "you should not use paths in config"
pictures:
  - *default_path
  - pics

4voto

Arnis L. Points 18316

Il me semble que YAML lui-même ne définit pas la manière de procéder .

La bonne nouvelle, c'est que le consommateur de YAML pourrait être en mesure de comprendre les variables.
Qu'est-ce qui utilisera votre YAML ?

0 votes

Mon fichier yaml sert de fichier de configuration. Ce que j'ai collé ci-dessus était juste un exemple, pour illustrer le problème.

0 votes

@ArnisL. par exemple celui-ci pour définir un chemin d'accès aux répertoires du code source lors de la construction d'un module distinct.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X