PyYAML dump format
Je sais qu'il y a quelques questions à propos de ce sur, mais je ne pouvais pas trouver ce que je cherchais.
Je suis en utilisant pyyaml à lire (.load()
) un .yml
fichier, de modifier ou d'ajouter une clé, puis l'écrire (.dump()
) de nouveau. Le problème est que je veux garder le format de fichier de post-décharge, mais il change.
Par exemple, j'ai modifier la clé en.test.index.few
- à-dire "Bye"
au lieu de "Hello"
Python:
with open(path, 'r', encoding = "utf-8") as yaml_file:
self.dict = pyyaml.load(yaml_file)
Puis, après la modification de la clé:
with open(path, 'w', encoding = "utf-8") as yaml_file:
dump = pyyaml.dump(self.dict, default_flow_style = False, allow_unicode = True, encoding = None)
yaml_file.write( dump )
Yaml:
Avant:
en:
test:
new: "Bye"
index:
few: "Hello"
anothertest: "Something"
Après:
en:
anothertest: Something
test:
index:
few: Hello
new: Bye
Est-il un moyen de garder le même format?, par exemple, le qoutes et de l'ordre. Suis-je utiliser le mauvais outil pour cela?
Je sais peut-être que le fichier d'origine, ce n'est pas tout à fait correct, mais je n'ai aucun contrôle dessus (c'est un Ruby on Rails fichier i18n).
Merci beaucoup.
yaml.dump
a undefault_style
argument. À l'aide dedefault_style='"'
de garder votre chaîne de valeurs de guillemets, mais vos clés et tous les autres types de valeur seront également enveloppé dans des guillemets doubles.- Merci!, Je vais garder cela à l'esprit, il aurait été vraiment utile si ce n'était pas pour les touches 🙁
- Vous aurez probablement un moment difficile de la commande de clés, aussi.
yaml.load
vous donne undict
; ses touches sont non-ordonnée.yaml.dump
probablement sorties dans l'ordre que l'itération va. - Le nouveau fichier représente exactement la même information (en YAML) que l'origine de fichier; il n'y a pas de raison de garder le même format.
- c'est vrai, mais je voulais garder le format, parce que c'est utile, étant donné le contexte de la sublime paquet que j'ai créé github.com/NicoSantangelo/sublime-text-i18n-rails
Vous devez vous connecter pour publier un commentaire.
Utilisation
ruamel.yaml
à la place.De La Bibliothèque De La Lutte! Un Conte de Deux Bibliothèques
PyYAML est effectivement mort et a été pendant plusieurs années. Pour compliquer les choses, le projet officiel de la maison à http://pyyaml.org semble avoir été prise récemment. Ce site a accueilli la PyYAML outil de suivi, de documentation et de téléchargements. De cette écriture, tous sont partis. Ce n'est rien de moins calamiteuse. Bienvenue à juste un autre jour dans l'open source.
ruamel.yaml
est activement maintenu. Contrairement à PyYAML,ruamel.yaml
prend en charge:yaml.dump()
faire un dump d'un dictionnaire chargé par un appel précédent àyaml.load()
:ruamel.yaml
habilement respecte tous entrée mise en forme. Tout. L'ensemble de la stylistique enchilada. L'ensemble de la littéraire shebang. Tous.De la bibliothèque de la Migration: Le Sentier de Code Larmes
Depuis
ruamel.yaml
est un PyYAML fourche et donc conforme à la PyYAML de l'API, de la commutation de PyYAML àruamel.yaml
dans des applications existantes est généralement aussi simple que de remplacer toutes les occurrences de ce:...avec ceci:
Que c'est.
Aucun autre changement ne devrait être nécessaire. Le
yaml.load()
etyaml.dump()
fonctions devraient continuer à se comporter comme prévu, avec l'avantage de support de YAML 1.2 et activement recevoir des corrections de bugs.Aller-retour de la Préservation et de Ce qu'Il Peut Faire pour Vous
Pour assurer la compatibilité avec PyYaml, le
yaml.load()
etyaml.dump()
fonctions ne pas effectuez des allers-retours à la conservation par défaut. Pour ce faire, transmettre explicitement:Loader=ruamel.yaml.RoundTripLoader
mot-clé paramètreyaml.load()
.Dumper=ruamel.yaml.RoundTripDumper
mot-clé paramètreyaml.dump()
.Un exemple gentiment "emprunté" de
ruamel.yaml
de la documentation:C'est fait. Commentaires, commande, devis, et le les espaces seront désormais conservés intacts.
tl;dr
Toujours utiliser
ruamel.yaml
. N'utilisez jamais de PyYAML.ruamel.yaml
vie. PyYAML est fétide d'un cadavre en décomposition dans le moisissent charnier terrain de PyPi.Vive
ruamel.yaml
.ruamel.yaml
un essai quand j'ai du temps libre, et d'accepter la réponse si ça fonctionne. Merci!ruamel.yaml
ne parvient pas à aller préserver aucun mise en forme (y compris mais non limité à la citation de style), c'est un bug. Envisager de soumettre une question àruamel.yaml
's problème de tracker. Le principal responsable deruamel.yaml
est assez réceptif et chaleureux, heureusement. Cheers!preserve_quotes=True
pendant le chargement, qui va envelopper les chaînes chargé avec des informations nécessaires pour le dumping. Voir aussi cette réponse#
et sont préservées. Mais dans le cas où vous serez en insérer de nouvelles valeurs, méfiez-vous que les commentaires/les lignes vides sont actuellement attaché à la cartographie des touches/de la séquence des éléments de avant le commentaire (c'est à dire des commentaires de collecte est gourmand), même si visuellement le pourrait être "proche" de la clé suivante/élémentPremière
Pour représenter les données du dictionnaire est utilisé le code suivant:
C'est pourquoi la commande est modifiée
Deuxième
D'informations sur la façon scalaire de type a été présentée (avec des guillemets ou pas) est perdu lors de la lecture (c'est l'approche principale de la bibliothèque)
Résumé
Vous pouvez créer propre classe basée sur la "Dumper" et à la surcharge de la méthode 'represent_mapping' pour le changement de comportement comment dictionnaire sera présenté
Pour enregistrer les informations concernant les guillemets doubles pour les scalaires, vous devez également créer propre classe basée sur le "Loader", mais j'ai peur qu'il va affecter et d'autres classes et faire qu'il est difficile
Dans mon cas, je veux
"
si la valeur contient un{
ou un}
, sinon rien. Par exemple:Pour effectuer cette, fonction de copie
represent_str()
à partir d'un fichier representer.py dans le module PyYaml et utiliser un autre style si la chaîne contient{
ou un}
:Pour l'utiliser dans votre code:
Dans ce cas, pas de diffences entre les clés et les valeurs, et c'est assez pour moi. Si vous voulez un style différent pour les clés et les valeurs, d'effectuer la même chose avec la fonction
represent_mapping