2010-10-29 4 views
1

-je utiliser la fonction vars() pour la première fois, et a remarqué ce comportement:Comment retourner les variables locales ([objet]) à partir de la fonction?

nodes = ['one', 'two', 'three'] 

for node in nodes: 
    vars()[node + '_'] = 'some calc ' + node 
    vars()[node] = vars()[node + '_'] 

print one 

Avec cet extrait des sorties Python some calc one comme prévu, mais si je l'utilise dans la fonction comme ceci:

def main(): 

    nodes = ['one', 'two', 'three'] 

    for node in nodes: 
     vars()[node + '_'] = 'some calc ' + node 
     vars()[node] = vars()[node + '_'] 

    print one 

main() 

il délivre en sortie NameError: global name 'one' is not defined

objet

vars() est dict:

{'node': 'three', 'three_': 'some calc three', 'two': 'some calc two', 'one': 'some calc one', 'two_': 'some calc two', 'three': 'some calc three', 'nodes': ['one', 'two', 'three'], 'one_': 'some calc one'} 

Maintenant, je voudrais savoir ce qui se passe en cette fonction est bien documenté et je ne peux pas trouver par exemple comment retourner ces variables si la fonction à l'intérieur

+0

Je viens de déclarer une nouvelle variable dict, et assigné des valeurs de vars() dans: d [node] = vars() [node]; retour d – romor

Répondre

0

vars() agit comme locals() si elle est appelée sans args, donc à partir de the docs:

Remarque: Le contenu de ce dictionnaire ne doit pas être modifié; les modifications peuvent ne pas affecter les valeurs des variables locales et libres utilisées par l'interpréteur.

2

La raison pour laquelle cela fonctionne lorsqu'il est appelé dans un champ de modules global », est qu'il est équivalent à globals() dans ce contexte qui est en fait un dictionnaire stocké par python. Les locals d'étendues non globales ne sont pas réellement un dictionnaire dans l'implémentation, (ceci pour éviter d'avoir à rechercher les clés du dictionnaire lors de leur accès) et donc il n'y a pas de vrai dictionnaire à retourner. Au lieu de cela, Python en crée un pour vous mais il n'est en aucun cas connecté au vrai tableau des variables locales. La seule façon que je connaisse pour insérer de nouveaux locaux dans un cadre d'exécution est d'utiliser exec ou eval mais il y a presque toujours une meilleure façon de faire ce que vous voulez qui ne nécessite pas de créer des locaux à la volée.

Si vous souhaitez créer des locals dans une trame non exécutable, vous pouvez lui appliquer des transformations de type bytecode, par ex. transformez les globals en locals, cellules ou constantes mais c'est une magie noire non triviale et, encore une fois, il y a certainement une meilleure façon de faire.

Votre question fait référence à des choses de retour mais je ne vois rien que vous retournez. Que veux-tu exactement retourner?

Je dirais que le nom que vous donnez vos valeurs de retour devrait avoir très peu d'impact car ce n'est pas le nom qu'ils seront donnés dans le cadre appelant. Pourquoi un simple dictionnaire ne suffit-il pas?

+0

Merci pour les explications. Je voulais que les noms soient conservés de cette façon car ils simplifient le code de ma connaissance limitée de Python. J'essaie d'analyser la réponse de Google Books (lien: http://www.google.com/books/feeds/volumes/g__6DX33JWUC) que j'ai dans la variable xml_data et de la transmettre pour un traitement supplémentaire. Voici cette fonction - (lien: http://codepad.org/ne4jZQ3k) Bien sûr, je pourrais étendre le code, mais cette approche me semblait bien – romor

+0

PS: Si pas évident, j'utilise lxml – romor

Questions connexes