2012-12-14 2 views
1

Je souhaite charger un objet à partir du fichier en utilisant eval. Cet objet est jeté dans le fichier de sorte qu'il est une expression de python valide - tous les types sont données avec leur nom de domaine complet, comme celui-ci:Importer automatiquement les modules nécessaires dans eval (...)

mod1.Class1(
    attr1=mod2.Class2(a=1,b=2), 
    attr2=[1,2,3,4], 
    attr3=mod1.submod1.Class3(), 
) 

Quand je nourris cela en eval, tous ces modules sont importés dans la portée où eval est appelée, donc je reçois soit NameError: name 'mod1' is not defined pour les modules de niveau supérieur, soit, lorsqu'ils sont importés, AttributeError: 'module' object has not attribute 'submod1' pour les sous-modules.

Existe-t-il une façon élégante de gérer cela? Je peux analyser NameError, exécuter __import__ et réessayer eval, mais je suis à perte comment obtenir ce qui s'est passé de AttributeError.

Pourrais-je transmettre l'expression à compile, parcourir l'AST et importer tout ce qui est nécessaire? Vous n'avez jamais travaillé avec l'AST, par exemple?

Remarque Je suis pas intéressé par la sécurité ici.

Répondre

1

Pourquoi ne pas utiliser pickle pour cela? Vous pouvez même __getstate__ et __setstate__ méthodes sur vos classes pour contrôler les aspects de la sérialisation et de l'instanciation. Semble sérieusement mieux que de faire votre propre chose eval().

Sinon, dans quelle mesure les valeurs dans votre format de sérialisation sont-elles contrôlées? C'est à dire. Peut-être que vous pouvez juste prédire quels modules seront nécessaires.

+0

J'ai besoin que les données soient lisibles par l'homme et facilement modifiables. Donc le cornichon est sorti. Les valeurs ne sont pas tellement contrôlées, et le paquet principal a trop de sous-modules dans plusieurs niveaux. – eudoxos

1

Si vous êtes marié à l'utilisation de Python complet (plutôt que de quelque chose de plus facilement analysable comme JSON ou YAML) pour vos données, la lecture des sons AST est assez faisable. Vous voudriez implémenter un ast.NodeVisitor et garder une trace des nœuds d'attribut visités.

Questions connexes