PyYAML : Contrôle de la commande d'éléments appelés par yaml.load()
J'ai un fichier de configuration yaml qui crée des enregistrements en db:
setting1:
name: [item,item]
name1: text
anothersetting2:
name: [item,item]
sub_setting:
name :[item,item]
lorsque je mets à jour ce fichier avec setting3 et de régénérer les dossiers en db par:
import yaml
fh = open('setting.txt', 'r')
setting_list = yaml.load(fh)
for i in setting_list:
add_to_db[i]
il est essentiel que l'ordre de leur paramètres (numéros d'identification en db) restent les mêmes à chaque fois que la messagerie instantanée de l'ajout à la db... et setting3 obtient juste ajouté à la yaml.load()'fin, ainsi que le numéro d'identification ne pas confondre tous les dossiers qui sont déjà dans la db ...
En ce moment à chaque fois que j'ajoute un autre paramètre et appel yaml.load() les documents chargés dans un ordre différent, qui résultats dans les différents ids. Je serais heureux de toutes les idées 😉
EDIT:
J'ai suivi abarnert conseils et a pris cette gist https://gist.github.com/844388
Fonctionne comme prévu merci !
PyYAML
, ou quelque chose d'autre? Il n'est pas intégré dans le yaml
module, et au moins deux PyPI paquets que vous donner un yaml
module. En général, chaque fois que vous utilisez un module tiers, vous devez vous dire où vous l'avez obtenu.Quel que soit le module que vous utilisez, vous devez raccorder la façon dont il convertit la cartographie des noeuds de Python, de sorte qu'il utilise un
collection.OrderedDict
au lieu d'un dict
. Avec d'autres modules d'ailleurs PyYAML, je n'ai aucune idée. Avec PyYAML
, c'est certainement possible, mais compliqué si vous êtes collant à haut niveau de commodité méthodes. D'ailleurs, quelqu'un a mentionné qu'il était plus facile de monkeypatch plutôt que d'utiliser la destinée des crochets.Im en utilisant PyYAML comme le titre de cette question suggère ... -> PyYAML : Contrôle de la commande d'éléments appelés par yaml.load(). Merci pour vos conseils!!!!
OriginalL'auteur zzart | 2012-11-08
Vous devez vous connecter pour publier un commentaire.
Le YAML spec dit clairement que la commande de clés à l'intérieur d'une cartographie est une "représentation détail" qui ne peut pas être invoqué. Si votre fichier de settings qui est déjà pas valide si elle s'appuie sur la cartographie, et vous seriez beaucoup mieux en utilisant valide YAML, si possible.
Bien sûr, YAML est extensible, et il n'y a rien qui vous empêche d'ajouter un "commandé" mappage de type à vos fichiers de paramètres. Par exemple:
Vous n'avez pas mentionné qui
yaml
module que vous utilisez. Il n'existe pas de module dans la bibliothèque standard, et il y a au moins deux paquets juste sur PyPI qui offrent des modules de ce nom. Cependant, je suppose que c'est PyYAML, car autant que je sais que c'est le plus populaire.La prolongation décrite ci-dessus est facile à analyser avec PyYAML. Voir http://pyyaml.org/ticket/29:
Maintenant, au lieu de:
Vous obtiendrez ceci:
Bien sûr, cela vous donne une
tuple
de clé-valeurtuple
s, mais vous pouvez facilement écrire un construct_ordereddict et obtenir uneOrderedDict
à la place. Vous pouvez également écrire un representer que les magasinsOrdereredDict
objets comme!omap
s, si vous avez besoin de la sortie ainsi que d'entrée.Si vous voulez vraiment crochet PyYAML à utiliser un
OrderedDict
au lieu d'undict
pour les mappages par défaut, il est assez facile à faire si vous êtes déjà travailler directement sur l'analyseur objets, mais plus difficile si vous voulez coller avec le haut niveau de commodité méthodes. Heureusement, mentionnées ci-dessus ticket est une application que vous pouvez utiliser. Rappelez-vous juste que vous n'êtes pas réel utilisant YAML plus, mais une variante, de sorte que tout autre logiciel qui s'occupe de vos fichiers peut, et sans doute, briser.OriginalL'auteur abarnert
oyaml
est une baisse-dans le remplacement pour PyYAML, ce qui vous permettra de charger des cartes danscollections.OrderedDict
au lieu d'un dicts. Juste pip de l'installer et de l'utiliser comme d'habitude - fonctionne sur Python 3 et Python 2.Démo avec votre exemple:
OriginalL'auteur wim
Vous pouvez maintenant utiliser ruaml.yaml pour cela.
De https://pypi.python.org/pypi/ruamel.yaml:
Vous devriez passer
Loader = ruamel.yaml.RoundTripLoader
à laload
méthode dans le but de préserver l'ordre.OriginalL'auteur jan
Dernier que j'ai entendu, PyYAML n'y sont pas favorables, mais il serait probablement facile de le modifier pour accepter un dictionnaire ou dictionnaire comme objet comme un point de départ.
OrderedDict
, tous les sous-dictionnaires seront toujoursdict
. Donc, ce que vous avez vraiment besoin est de le modifier à accepter un autre constructeur à utiliser à la place dedict
(et, idéalement, un pour chaque constructeur qu'il utilise, bien que les autres ne soient pas utiles comme souvent).OriginalL'auteur dstromberg
Pour un seul élément qui est connu pour être un commandés dictionnaire juste faire les éléments d'une liste et utilisé des collections.OrderedDict:
OriginalL'auteur mybrid