2011-02-02 19 views
8

Hay una parte de __import__ en la documentación de Python, que no entiendo:¿Para qué sirven los parámetros `globals` y` locals` en Python __import__?

__import__(name[, globals[, locals[, fromlist[, level]]]])

La función importa el módulo name, potencialmente mediante el dado globals y locals para determinar cómo interpretar la name en un contexto de paquete. La implementación estándar no usa su argumento locals, y usa su globals solo para determinar el contexto del paquete de la declaración de importación.

¿Qué hay para "interpretar" sobre el nombre del módulo? ¿Qué es el contexto del paquete?

Una llamada ejemplo usando estos parámetros tiene el siguiente aspecto:

spam = __import__('spam', globals(), locals(), [], -1) 

¿Por qué sólo el ejemplo globals() y locals() a la función? ¿Qué sucede cuando solo proporciono globals()? ¿O ninguno?

Probablemente me falta algo de la lógica del espacio de nombres en relación con la importación de módulos. ¿Podría señalarme un artículo que explica esto/tiene ejemplos con la función __import__?

+1

¿No debería esta pregunta trasladarse a StackOverflow? – EOL

+0

Esto es gracioso, comencé a escribir esto en SO, pero estaba pensando si debería publicarlo en los programadores.SE en su lugar ... claramente necesito mirar las preguntas frecuentes ... –

+0

Debe seleccionar una de las respuestas a continuación como el respuesta aceptada para esta pregunta. En mi humilde opinión, la respuesta de 9000 da en el clavo explicando qué hace Python con 'globales 'para determinar el espacio de nombres del módulo. – Kumba

Respuesta

4

La implementación estándar no utiliza su argumento locals en absoluto, y utiliza su globals sólo para determinar el contexto del paquete de la declaración import.

(de docs.python.org)

todavía no tengo ni idea de cómo se utilizan globals; ¿Qué variable global puede afectar la forma en que funciona la declaración import?

EDIT: Después de mirar import.c en Python 2.5 fuente encontré que __import__ espera encontrar ya sea __name__ o __path__ en globals con el fin de aumentar la búsqueda de importación ruta relativa a la ruta (s) que se encuentra en una de estas variables, en ese orden.

+0

Hablando de obtuso. Así que, básicamente, en lugar de pasar esta enorme masa de memoria conteniendo todos los globales (asumiendo que Python no lo hace por referencia), uno puede pasar un dict simple con una sola clave, '" __name __ "', establecido en el módulo de llamada el atributo '__name__', y Python trabajará con él. La documentación de Python debe actualizarse con este tidbit de información. – Kumba

+0

@Kumba: supongamos que Python hace todo por referencia, excepto algunas operaciones numéricas primitivas. Los dicts definitivamente se pasan por referencia. Python 3.3 incluso introduce una implementación de dicts que comparten claves, es decir, también se accede a las claves por referencia. Hable sobre la coherencia del caché si quiere refunfuñar :) – 9000

+0

Habiendo jugado realmente (y poseyendo) hardware no coherente, solo puedo comenzar a imaginarme esa pesadilla. Afortunadamente (o tristemente, haga su elección), el código que escribí en Python tiene que ejecutarse, al menos, en Python 2.4. He evitado 3.x porque sé que terminó completamente el idioma y gran parte de mi código probablemente no funcionaría sin una reescritura seria. – Kumba

0

¿Qué hay para "interpretar" sobre el nombre del módulo? ¿Qué es el contexto del paquete?

Al entrar en

>>> a 

Python debe "interpretar" ese nombre. ¿Es un global? ¿Es un local?

>>> def f(x): 
... return x * a 

Ahora, x es claramente local. a tiene que ser "interpretado". ¿Global? ¿Local?

¿Por qué el ejemplo proporciona globals() y locals() a la función? ¿Qué sucede cuando solo brindo globals()?¿O ninguno?

Pruébalo y mira. Seriamente. Es más fácil jugar con él que preguntar.

Lo importante es que las cosas que usted hace en el indicador >>> son globales.

Tendrá que definir funciones que crearán un contexto local para que pueda ver las diferencias entre global y local.

+0

Ok, jugaré un poco :) –

+0

La verdad graciosa^W es que un módulo importado ignora los valores casi globales del módulo que importa, y '__import__' ignora por completo el parámetro' locals'. De lo contrario, tienes razón :) – 9000

1

globals se utiliza para determinar el contexto actual en el que se llama a la importación. Por ejemplo:

""" 
/myproject/a/b.py 
/myproject/a/foo.py 
/myproject/c/d.py 
/myproject/c/foo.py 
""" 

# Which foo gets imported? 

import foo #1 
foo = __import__('foo') #2 

Ellos no son los mismos, ya que no hay manera (Fácil) en # 2 saber de qué módulo de la importación está siendo llamado desde. La función __import__ necesita saber cuál es el módulo actual para importar realmente el foo correcto.

Internamente en __import__(), globals se utiliza para obtener la referencia en el módulo actual que invoca la importación. Desde el __import__source code:.

devolver el paquete en que una mercancía se está realizando globales Si viene desde el foo.bar.bat módulo (no es en sí un paquete), esto devuelve la entrada de sys.modules foo.bar. Si global es de un paquete init .py, se devuelve la entrada del paquete en sys.modules, como referencia prestada.

+0

Digamos que hay 'import foo' en' b.py' y 'd.py'. ¿Cómo no sabe Python cuál importar? En el caso de 'b.py', ¿por qué buscaría' foo' en '../c'/? –

+0

Si hay 'import foo' en'/myproject/e.py', eso no debería funcionar. Ya sea 'import a.foo' o' import c.foo'. Lo siento ... Parece que no puedo dar un ejemplo que podría causar problemas, ¿podría darme una pista? –

Cuestiones relacionadas