2014-06-06 7 views
0

Je suis confus au sujet de l'espace de noms et la portée des variables en pythoncomment accéder à la variable globale dans la portée __main__?

Supposons que j'ai un test.py:

# -*- coding: utf-8 -*- 
""" 
@author: jason 
""" 

if __name__ == '__main__': 
    global strName 
    print strName 

puis, je définir une variable nommée strName et essayez d'accéder dans la test.py, mais il renvoie une erreur:

In [9]: strName = "Joe" 

In [10]: run test.py hello 
--------------------------------------------------------------------------- NameError        Traceback (most recent call last) C:\Anaconda\lib\site-packages\IPython\utils\py3compat.pyc in execfile(fname, glob, loc) 
    195    else: 
    196     filename = fname 
--> 197    exec compile(scripttext, filename, 'exec') in glob, loc 
    198  else: 
    199   def execfile(fname, *where): 

d:\playground\test.py in <module>() 
    13   print "hello" 
    14   global strName 
---> 15   print strName 
    16 

NameError: global name 'strName' is not defined 

In [11]: 

Je me demandais pourquoi cela se produit et est-il possible d'accéder à strName test.py?

+0

a. Vous ne définissez pas '' strName''. b. Vous devez importer '' test''. Par exemple: '' from import import strName'' –

+1

Les instructions 'if' ne créent pas de nouvelle portée (et' global' n'a pas de sens dans une portée de module). – user2864740

Répondre

1

global est pas globale. global est au niveau du module; vivent réellement dans le module __builtin__ (builtins en Python 3). L'utilisation d'une déclaration global au niveau du module est redondante.

Je recommande fortement vos données à test.py une autre manière, par exemple en définissant une fonction là-bas et passer votre chaîne comme argument:

test.py:

def print_thing(thing): 
    print thing 

autre code veut utiliser test.py:

import test 
test.print_thing("Joe") 
+0

Je n'ai pas testé, et je ne testerai jamais, mais je crois: 'globals(). Update ({'strName': 'Joe'})' devrait fonctionner. Bien que ce commentaire seul me brûle les mains du pur mal que cette déclaration incarne, dans le cas où cela fonctionne. – Dair

+0

@anon: 'globals' est aussi au niveau du module. 'import __builtin__; __builtin __. strName = "Joe" 'fonctionne, bien que ce soit quelque chose à faire seulement en cas de nécessité extrême. – user2357112

0

Global est spécifique aux cas où vous avez défini une variable en dehors d'une méthode et que vous souhaitez l'utiliser dans cette méthode sans passer de paramètres. Il est placé en haut de la méthode afin que python traite cette variable comme une variable globale, plutôt qu'une nouvelle variable locale avec le même nom. Global n'est pas un moyen de déclarer des variables, et puisque strName n'est pas en existence, global ne peut pas savoir où se trouve strName.

+0

En Python 3, ceci a été changé en '' nonlocal'' pour éviter toute confusion. –

+0

@ JamesMills: Ce n'était pas le cas. 'global' est toujours là; 'nonlocal' est spécifiquement pour se référer aux variables des étendues externes mais non globales. Vous pouvez voir dans la [référence du langage] (https://docs.python.org/3/reference/simple_stmts.html#the-nonlocal-statement) que la définition interdit de l'utiliser pour les variables globales. – user2357112

+0

Ahh vous avez raison :) Mon erreur. –

1

test.py:

strName = "John Doe" 
print strName 

Interactive Shell:

$ python 
>>> from test import strName 
>>> print strName 
John Doe 
+0

Je pense que cela manque le point car il veut que le module accède à 'strName' de l'utilisateur, * pas * l'inverse. – Dair

+0

Oui, je peux voir que - Cependant ce que l'OP essaie de faire clairement ne fonctionnera pas sans un peu de magie :) –

+0

@James Mills merci, mais je me demande encore quelle est la portée de strName si je le définis par entrer strName = 'Joe' dans le shell? et comment puis-je accéder à cette variable dans un module (sauf passer strName en tant que paramètre de la fonction)? –

Questions connexes