2013-06-19 6 views
3

J'essaie de créer un format yaml qui me permet de créer un objet à l'intérieur d'un autre objet. Dans cet exemple, j'essaie de créer un objet Machine d'état et de le remplir en même temps avec des états et des connexions entre eux.Python, yaml objets imbriqués

yaml.load(""" 
!statemachine { 
    states: [ 
     !state { name: p1 }, 
     !state { name: p2 }, 
     !state { name: p3 },], 
    connections: 
     [!connection { 'pim' : [p1,p2]}]} 
""") 

! StateMachine avoir un constructeur qui génère un objet de type MyStateMachine

! État avoir un constructeur qui génère un objet de type MyState

! Connexion avoir un constructeur qui doit utiliser l'objet généré avec le nom p1 et ajouter une connexion à ce

J'ai 2 problèmes ici:

1 - La construction ou pour état est appelé après l'StateMachine est créé et les états ne sont pas présents à l'intérieur

2 - Récupération du p1 d'objet et appeler la méthode add_connection dessus.

Merci à l'avance

+0

C'est dur. Lorsque j'avais besoin de quelque chose comme ça (aller d'une chaîne qui est la valeur pour une clé spécifique dans un autre objet/mappage à une référence) j'ai ajouté une étape de désérialisation personnalisée au sommet des structures de données YAML natives. – delnan

Répondre

6

permet d'essayer la vraie syntaxe pyyaml pour les objets

myyaml.py:

import yaml,sys 

class StateMachine(object): 
    pass 

class State(object): 
    pass 

class Connection(object): 
    pass 

if __name__ == '__main__': 
    o = yaml.load(""" 
    !!python/object:myyaml.StateMachine { 
     states: [ 
      !!python/object:myyaml.State { name: p1 }, 
      !!python/object:myyaml.State { name: p2 }, 
      !!python/object:myyaml.State { name: p3 },], 
     connections: 
      [  !!python/object:myyaml.Connection { 'pim' : [p1,p2]}]} 
    """) 
    print o.states[0].name 
    print o.states[1].name 
    print o.connections[0].pim 
    sys.exit(0) 

Gets:

p1 
p2 
['p1', 'p2'] 

Et jamais essayer le yaml.load() dans le bloc racine du module, utilisez toujours if __name__ == '__main__' ou appelez-le dans un onction que vous vous assurez qu'il sera appelé une fois.

s'il vous plaît noter que la déclaration de YAML:

!!python/object:myyaml.State { name: p1 }, 

À ce stade yaml tente d'importer à nouveau le myyaml.py, dans un autre contexte, et les seront exécutés tous les codes dans la racine du module, si vous mettez yaml .load ou quelque chose comme ça dans la racine du module, vous pouvez rencontrer une boucle infinie, ou un résultat inattendu.

+0

Merci ça a marché comme un charme: D – jpereira