¿Cuál es la diferencia entre globals (), locals () y vars ()?

¿Cuál es la diferencia entre globals() , locals() y vars() ? ¿A qué vuelven? ¿Son útiles las actualizaciones de los resultados?

Cada uno de estos devuelve un diccionario:

  • globals() siempre devuelve el diccionario del espacio de nombres del módulo
  • locals() siempre devuelve un diccionario del espacio de nombres actual
  • vars() devuelve un diccionario del espacio de nombres actual (si se llama sin argumento) o el diccionario del argumento.

locals y vars podrían usar alguna explicación más. si se llama a locals() dentro de una función, construye un diccionario del espacio de nombres de la función a partir de ese momento y lo devuelve – cualquier asignación de nombre adicional no se reflejará en el diccionario devuelto, y cualquier asignación al diccionario no se reflejará en el real espacio de nombres local:

 def test(): a = 1 b = 2 huh = locals() c = 3 print(huh) huh['d'] = 4 print(d) 

Nos da:

 {'a': 1, 'b': 2} Traceback (most recent call last): File "test.py", line 30, in  test() File "test.py", line 26, in test print(d) NameError: global name 'd' is not defined 

Dos notas:

  1. Este comportamiento es específico de CPython; otros Pythons pueden permitir que las actualizaciones regresen al espacio de nombres local
  2. En CPython 2.x es posible hacer que esto funcione al poner una línea exec "pass" en la función.

Si se llama a locals() fuera de una función, devuelve el diccionario real que es el espacio de nombres actual. Los cambios adicionales en el espacio de nombres se reflejan en el diccionario, y los cambios en el diccionario se reflejan en el espacio de nombres:

 class Test(object): a = 'one' b = 'two' huh = locals() c = 'three' huh['d'] = 'four' print huh 

Nos da:

 { 'a': 'one', 'b': 'two', 'c': 'three', 'd': 'four', 'huh': {...}, '__module__': '__main__', } 

Hasta ahora, todo lo que he dicho sobre locals() también es válido para vars() … aquí está la diferencia: vars() acepta un solo objeto como argumento, y si le das un objeto, devuelve el __dict__ de eso objeto. Si ese objeto no era una función, el __dict__ devuelto es el espacio de nombres de ese objeto:

 class Test(object): a = 'one' b = 'two' def frobber(self): print self.c t = Test() huh = vars(t) huh['c'] = 'three' t.frobber() 

lo que nos da:

 three 

Si el objeto era una función, aún obtienes su __dict__ , pero a menos que estés haciendo cosas divertidas e interesantes, probablemente no sea muy útil:

 def test(): a = 1 b = 2 print test.c huh = vars(test) # these two lines are the same as 'test.c = 3' huh['c'] = 3 test() 

lo que nos da:

 3