Funciones locals() y globals() en Python

Python Incorpora dos funciones locals() y globals(), que proporcionan acceso de tipo diccionario a las variables locales y globales.

La forma en que Python gestiona las variables se debe a los espacios de nombre (namespaces) donde se lleva un seguimiento de las variables. Un espacio de nombres se puede tratar como un diccionario donde las keys son los nombres de las variables y las values son los valores de dichas variables.

En realidad, se puede acceder a un espacio de nombres de Python como a un diccionario:

>>>
>>> a = 3
>>> 
>>> def foo():
... a = 7
... print locals()
... 
>>> locals()
{'a': 3, 'foo': <function esp at 0xb73c0684>, '__builtins__': <module '__builtin__' (built-in)>, '__package__': None, '__name__': '__main__', '__doc__': None}
>>> foo()
{'a': 7}
>>>

En cualquier momento de la ejecución de un programa en Python se puede acceder a varios espacios de nombre. Por ejemplo, cada función tiene su namespace llamado espacio “local”, el cual contiene las variables definidas por la función, incluyendo sus argumentos y variables definidas localmente.

Ahora cada módulo cuenta con su propio namespace denominado espacio “global”, que contiene las variables del módulo, incluyendo sus funciones, clases y otros módulos que haya importado, así como variables y constantes del módulo.

Y hay un espacio de nombres “incorporado”, accesible desde cualquier módulo, que contiene funciones del lenguaje y excepciones.

Acceso a los namespace:

En Python cuando es solicitado el valor de una variable “x”, Python realiza una búsqueda de esa variable en todos los namespaces disponibles, por orden:

1. Espacio local, específico de la función o método de clase actual. Si la función define una variable local x, o tiene un argumento x, Python usará ésta y dejará de buscar.
2. Espacio global, específico al módulo actual. Si el módulo ha definido una variable, función o clase llamada x, Python usará ésta y dejará de buscar.
3. Espacio incorporado, global a todos los módulos. Como último recurso, Python asumirá que x es el nombre de una función o variable incorporada por el lenguaje.

Si Python no encuentra una referencia a “x” en ninguno de los namespaces, lanzará una excepción “NameError”. En Python podemos acceder a los namespaces directamente durante la ejecución.

LOCALS:

Al espacio local de nombres podemos acceder mediante la función incorporada “locals()”

>>> 
>>> def foo(b):
... c = 8
... print locals()
... 
>>> foo(6)
{'c': 8, 'b': 6}
>>>

Como podemos notar la función locals(), nos muestra un diccionario de par clave/valor con las variables definidas en el namespace por la función foo.

GLOBALS:

Al espacio global(del módulo) es accesible mediante la función globals. Lo que hace locals() con los namespaces locales, lo hace globals() para el espacio de nombres global(módulo). El espacio de nombres del módulo no sólo incluye variables y constantes del módulo, también incluye todas las funciones y clases definidas en él. Además, incluye cualquier cosa que se haya importado dentro del módulo.

De aquí la diferencia entre “from módulo import” e “import módulo”. Con “import módulo” se importa el módulo en sí, pero retiene su espacio de nombres, y esta es la razón por la que necesita usar el nombre del módulo para acceder a cualquiera de sus funciones o atributos: “módulo.función”. Pero con “from módulo import”, en realidad está importando funciones y atributos específicos de otro módulo al espacio de nombres del suyo propio, que es la razón por la que puede acceder a ellos directamente sin hacer referencia al módulo del que vinieron originalmente. Con la función globals puede ver esto en funcionamiento.

>>> import sys
>>> from time import asctime
>>> 
>>> class A(object):
... pass
... 
>>> d = 5
>>> 
>>> def foo(arg):
... return arg
... 
>>> 
>>> for k, v in globals().items():
... print k, "=", v
... 
A = <class '__main__.A'>
d = 5
__builtins__ = <module '__builtin__' (built-in)>
__package__ = None
sys = <module 'sys' (built-in)>
asctime = <built-in function asctime>
__name__ = __main__
foo = <function foo at 0xb73729cc>
__doc__ = None
>>> 
>>> 
>>> def foo2(arg):
... i = 9
... for k, v in globals().items():
... print k, "=", v
... 
>>> foo2(1000)
A = <class '__main__.A'>
d = 5
__builtins__ = <module '__builtin__' (built-in)>
k = __doc__
v = None
__package__ = None
sys = <module 'sys' (built-in)>
asctime = <built-in function asctime>
__name__ = __main__
foo = <function foo at 0xb73729cc>
__doc__ = None
foo2 = <function foo2 at 0xb7372d14>
>>>

Como podemos notar en el espacio de nombres global dentro de la función foo2(), no podemos hallar sus argumentos.

LOCALS es de sólo lectura, GLOBALS no.

Se puede obtener dinámicamente el valor de variables arbitrarias usando las funciones locals y globals, proporcionando el nombre de la variable en una cadena.

>>> 
>>> def foo(arg):
... x = 1
... print locals()
... locals()['x'] = 2
... print "x=", x
... print locals()
... 
>>> foo(4)
{'x': 1, 'arg': 4}
x= 1
{'x': 1, 'arg': 4}
>>> 
>>> z = 7
>>> globals()['z'] = 8
>>> print "z=", z
z= 8
>>> globals()
{'z': 8, '__builtins__': <module '__builtin__' (built-in)>, '__package__': None, '__name__': '__main__', 'foo': <function foo at 0xb73cd684>, '__doc__': None}
>>>

 

La gran diferencia es que locals() no devuelve el verdadero espacio de nombres local, sino una copia (Así que cambiarlo no hace nada con los valores de las variables del espacio local); y en cambio globals() devuelve el verdadero espacio de nombres global, no una copia (Así que los cambios que haga en el diccionario devuelto por globals afectan directamente a las variables globales).

 

Apartes tomados de:
http://www.diveintopython.net

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s