¿Qué hace realmente from __future__ import absolute_import?

167
Two-Bit Alchemist 2015-11-17 10:18.

He respondido a una pregunta con respecto a las importaciones absolutas en Python, que pensé que comprendía basado en la lectura de la lista de cambios Python 2.5 y acompañando PEP . Sin embargo, al instalar Python 2.5 e intentar crear un ejemplo de uso adecuado from __future__ import absolute_import, me doy cuenta de que las cosas no están tan claras.

Directamente del registro de cambios vinculado anteriormente, esta declaración resumió con precisión mi comprensión del cambio de importación absoluto:

Digamos que tiene un directorio de paquetes como este:

pkg/
pkg/__init__.py
pkg/main.py
pkg/string.py

Esto define un paquete llamado que pkgcontiene los submódulos pkg.mainy pkg.string.

Considere el código en el módulo main.py. ¿Qué pasa si ejecuta la sentencia import string? En Python 2.4 y anteriores, primero buscará en el directorio del paquete para realizar una importación relativa, encuentra pkg / string.py, importa el contenido de ese archivo como pkg.stringmódulo y ese módulo está vinculado al nombre "string"en el pkg.mainespacio de nombres del módulo.

Así que creé esta estructura de directorio exacta:

$ ls -R
.:
pkg/

./pkg:
__init__.py  main.py  string.py

__init__.pyy string.pyestán vacíos. main.pycontiene el siguiente código:

import string
print string.ascii_uppercase

Como era de esperar, ejecutar esto con Python 2.5 falla con un AttributeError:

$ python2.5 pkg/main.py
Traceback (most recent call last):
  File "pkg/main.py", line 2, in <module>
    print string.ascii_uppercase
AttributeError: 'module' object has no attribute 'ascii_uppercase'

Sin embargo, más adelante en el registro de cambios 2.5, encontramos esto (énfasis agregado):

En Python 2.5, puede cambiar importel comportamiento a importaciones absolutas usando una from __future__ import absolute_importdirectiva. Este comportamiento de importación absoluta se convertirá en el predeterminado en una versión futura (probablemente Python 2.7). Una vez que las importaciones absolutas sean las predeterminadas, import stringsiempre encontrará la versión de la biblioteca estándar.

Creé así pkg/main2.py, idéntico main.pypero con la futura directiva de importación adicional. Ahora luce así:

from __future__ import absolute_import
import string
print string.ascii_uppercase

Sin embargo, ejecutar esto con Python 2.5 ... falla con un AttributeError:

$ python2.5 pkg/main2.py
Traceback (most recent call last):
  File "pkg/main2.py", line 3, in <module>
    print string.ascii_uppercase
AttributeError: 'module' object has no attribute 'ascii_uppercase'

Esto contradice bastante rotundamente la afirmación de que import stringserá siempre encontrar la versión STD-lib con importaciones en términos absolutos habilitadas. Es más, a pesar de la advertencia de que las importaciones absolutas están programadas para convertirse en el "nuevo comportamiento predeterminado", encontré este mismo problema usando Python 2.7, con o sin la __future__directiva:

$ python2.7 pkg/main.py
Traceback (most recent call last):
  File "pkg/main.py", line 2, in <module>
    print string.ascii_uppercase
AttributeError: 'module' object has no attribute 'ascii_uppercase'

$ python2.7 pkg/main2.py
Traceback (most recent call last):
  File "pkg/main2.py", line 3, in <module>
    print string.ascii_uppercase
AttributeError: 'module' object has no attribute 'ascii_uppercase'

así como Python 3.5, con o sin (asumiendo que la printdeclaración se cambia en ambos archivos):

$ python3.5 pkg/main.py
Traceback (most recent call last):
  File "pkg/main.py", line 2, in <module>
    print(string.ascii_uppercase)
AttributeError: module 'string' has no attribute 'ascii_uppercase'

$ python3.5 pkg/main2.py
Traceback (most recent call last):
  File "pkg/main2.py", line 3, in <module>
    print(string.ascii_uppercase)
AttributeError: module 'string' has no attribute 'ascii_uppercase'

He probado otras variaciones de esto. En lugar de string.py, he creado un módulo vacío - un directorio llamado stringque contiene sólo un vacío __init__.py- y en lugar de la emisión de las importaciones de main.py, tengo cd'd a pkge importaciones ejecutar directamente desde el REPL. Ninguna de estas variaciones (ni una combinación de ellas) cambió los resultados anteriores. No puedo conciliar esto con lo que he leído sobre la __future__directiva y las importaciones absolutas.

Me parece que esto se explica fácilmente por lo siguiente (esto es de los documentos de Python 2, pero esta declaración permanece sin cambios en los mismos documentos para Python 3):

sys.path

(...)

Como se inicializó al inicio del programa, el primer elemento de esta lista path[0]es el directorio que contiene el script que se utilizó para invocar al intérprete de Python. Si el directorio de la secuencia de comandos no está disponible (por ejemplo, si el intérprete se invoca de forma interactiva o si la secuencia de comandos se lee desde la entrada estándar), path[0]es la cadena vacía, que dirige a Python a buscar módulos en el directorio actual primero.

Entonces, ¿qué me estoy perdiendo? ¿Por qué la __future__declaración aparentemente no hace lo que dice, y cuál es la resolución de esta contradicción entre estas dos secciones de documentación, así como entre el comportamiento descrito y real?

2 answers

104
user2357112 supports Monica 2015-11-17 10:35.

El registro de cambios está redactado de manera descuidada. from __future__ import absolute_importno le importa si algo es parte de la biblioteca estándar y import stringno siempre le dará el módulo de biblioteca estándar con importaciones absolutas activadas.

from __future__ import absolute_importsignifica que si usted import string, Python siempre buscará un stringmódulo de nivel superior , en lugar de current_package.string. Sin embargo, no afecta la lógica que usa Python para decidir qué archivo es el stringmódulo. Cuando tu lo hagas

python pkg/script.py

pkg/script.pyno parece parte de un paquete para Python. Siguiendo los procedimientos normales, el pkgdirectorio se agrega a la ruta y todos los .pyarchivos en el pkgdirectorio se ven como módulos de nivel superior. import stringencuentra pkg/string.pyno porque esté haciendo una importación relativa, sino porque pkg/string.pyparece ser el módulo de nivel superior string. stringNo surge el hecho de que este no es el módulo de biblioteca estándar .

Para ejecutar el archivo como parte del pkgpaquete, puede hacer

python -m pkg.script

En este caso, el pkgdirectorio no se agregará a la ruta. Sin embargo, el directorio actual se agregará a la ruta.

También puede agregar un texto estándar para pkg/script.pyque Python lo trate como parte del pkgpaquete incluso cuando se ejecuta como un archivo:

if __name__ == '__main__' and __package__ is None:
    __package__ = 'pkg'

Sin embargo, esto no afectará sys.path. Necesitará un manejo adicional para eliminar el pkgdirectorio de la ruta, y si pkgel directorio principal no está en la ruta, deberá pegarlo también en la ruta.

45
Bakuriu 2015-11-17 10:34.

La diferencia entre importaciones absolutas y relativas entra en juego solo cuando se importa un módulo de un paquete y ese módulo importa otro submódulo de ese paquete. Ver la diferencia:

$ mkdir pkg
$ touch pkg/__init__.py
$ touch pkg/string.py
$ echo 'import string;print(string.ascii_uppercase)' > pkg/main1.py
$ python2
Python 2.7.9 (default, Dec 13 2014, 18:02:08) [GCC] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pkg.main1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "pkg/main1.py", line 1, in <module>
    import string;print(string.ascii_uppercase)
AttributeError: 'module' object has no attribute 'ascii_uppercase'
>>> 
$ echo 'from __future__ import absolute_import;import string;print(string.ascii_uppercase)' > pkg/main2.py
$ python2
Python 2.7.9 (default, Dec 13 2014, 18:02:08) [GCC] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pkg.main2
ABCDEFGHIJKLMNOPQRSTUVWXYZ
>>> 

En particular:

$ python2 pkg/main2.py
Traceback (most recent call last):
  File "pkg/main2.py", line 1, in <module>
    from __future__ import absolute_import;import string;print(string.ascii_uppercase)
AttributeError: 'module' object has no attribute 'ascii_uppercase'
$ python2
Python 2.7.9 (default, Dec 13 2014, 18:02:08) [GCC] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pkg.main2
ABCDEFGHIJKLMNOPQRSTUVWXYZ
>>> 
$ python2 -m pkg.main2
ABCDEFGHIJKLMNOPQRSTUVWXYZ

Tenga en cuenta que python2 pkg/main2.pytiene un comportamiento diferente al iniciar python2y luego importar pkg.main2(que es equivalente a usar el -mconmutador).

Si alguna vez desea ejecutar un submódulo de un paquete, utilice siempre el -mconmutador que evita que el intérprete encamine la sys.pathlista y maneja correctamente la semántica del submódulo.

Además, prefiero usar importaciones relativas explícitas para los submódulos de paquetes, ya que proporcionan más semántica y mejores mensajes de error en caso de falla.

Related questions

MORE COOL STUFF

La estrella de HGTV, Christina Hall, revela que tiene 'envenenamiento por mercurio y plomo' probablemente por voltear 'casas asquerosas'

La estrella de HGTV, Christina Hall, revela que tiene 'envenenamiento por mercurio y plomo' probablemente por voltear 'casas asquerosas'

La estrella de HGTV, Christina Hall, revela que le diagnosticaron envenenamiento por mercurio y plomo, probablemente debido a su trabajo como manipuladora de casas.

La estrella de 'Love Is Blind' Brennon Lemieux responde a los cargos de violencia doméstica

La estrella de 'Love Is Blind' Brennon Lemieux responde a los cargos de violencia doméstica

Recientemente salió a la luz un informe policial que acusa a la estrella de 'Love Is Blind', Brennon, de violencia doméstica. Ahora, Brennon ha respondido a los reclamos.

Wynonna Judd se dio cuenta de que ahora es la matriarca de la familia Judd en un momento festivo de pánico

Wynonna Judd se dio cuenta de que ahora es la matriarca de la familia Judd en un momento festivo de pánico

Conozca cómo Wynonna Judd se dio cuenta de que ahora es la matriarca de la familia mientras organizaba la primera celebración de Acción de Gracias desde que murió su madre, Naomi Judd.

Experto en lenguaje corporal explica los 'paralelos' entre Kate Middleton y la princesa Diana

Experto en lenguaje corporal explica los 'paralelos' entre Kate Middleton y la princesa Diana

Descubra por qué un destacado experto en lenguaje corporal cree que es fácil trazar "tales paralelismos" entre la princesa Kate Middleton y la princesa Diana.

Los láseres arrojan luz sobre por qué necesita cerrar la tapa antes de descargar

Los láseres arrojan luz sobre por qué necesita cerrar la tapa antes de descargar

Los inodoros arrojan columnas de aerosol invisibles con cada descarga. ¿Como sabemos? La prueba fue capturada por láseres de alta potencia.

The Secrets of Airline Travel Quiz

The Secrets of Airline Travel Quiz

Air travel is far more than getting from point A to point B safely. How much do you know about the million little details that go into flying on airplanes?

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

¿Caduca el repelente de insectos?

¿Caduca el repelente de insectos?

¿Sigue siendo efectivo ese lote de repelente de insectos que te quedó del verano pasado? Si es así, ¿por cuánto tiempo?

Estados Unidos podría evitarse el horror del nuevo gran horneado británico

Estados Unidos podría evitarse el horror del nuevo gran horneado británico

Si este tráiler de pesadilla de la temporada más reciente de Great British Bake Off te asustó y te hizo no volver a ver el programa, es posible que tengas suerte: PBS no ha decidido si se transmitirá o no la última temporada en los Estados Unidos. actualización, para aquellos que no siguen sin aliento este tipo de drama de nicho: el presentador Paul Hollywood y la hermosa carpa llena de batidoras de colores pastel y cuadros se trasladaron de la BBC al Canal 4; Mary Berry, Sue Perkins y Mel Giedroyc renunciaron.

Atún como Oh, Hello llega a Netflix

Atún como Oh, Hello llega a Netflix

Foto: Netflix Oh, Hello On Broadway (Netflix): Después de llegar a Broadway el año pasado, los dos locos del Upper West Side interpretados por John Mulaney y Nick Kroll finalmente llegaron a Netflix. El especial consta del espectáculo en el escenario, algunos momentos entre bastidores y un invitado muy especial de “Too Much Tuna”.

Actualice a un Sonicare por tan solo $ 30

Actualice a un Sonicare por tan solo $ 30

¿Quiere probar un cepillo de dientes Sonicare sin gastar mucho dinero en uno de sus modelos favoritos de gama alta? Puede comprar un kit de la Serie 2 o Serie 3 por tan solo $ 30 hoy en Amazon. Haga clic aquí para ver la lista completa de modelos elegibles y tenga en cuenta que se descontarán $ 10 adicionales en su carrito.

Ponle una tapa. En realidad, ponle una tapa a todo. Consigue 12 tapas de cocina elásticas de silicona por $14. [Exclusivo]

Ponle una tapa. En realidad, ponle una tapa a todo. Consigue 12 tapas de cocina elásticas de silicona por $14. [Exclusivo]

Tapas elásticas de silicona de Tomorrow's Kitchen, paquete de 12 | $14 | Amazonas | Código promocional 20OFFKINJALids son básicamente los calcetines de la cocina; siempre perdiéndose, dejando contenedores huérfanos que nunca podrán volver a cerrarse. Pero, ¿y si sus tapas pudieran estirarse y adaptarse a todos los recipientes, ollas, sartenes e incluso frutas en rodajas grandes que sobran? Nunca más tendrás que preocuparte por perder esa tapa tan específica.

Patinaje artístico de EE. UU. 'frustrado' por falta de decisión final en evento por equipos, pide una decisión justa

Patinaje artístico de EE. UU. 'frustrado' por falta de decisión final en evento por equipos, pide una decisión justa

El equipo está a la espera de las medallas que ganó en los Juegos Olímpicos de Invierno de 2022 en Beijing, ya que se está resolviendo un caso de dopaje que involucra a la patinadora artística rusa Kamila Valieva.

Los compradores de Amazon dicen que duermen 'como un bebé mimado' gracias a estas fundas de almohada de seda que cuestan tan solo $ 10

Los compradores de Amazon dicen que duermen 'como un bebé mimado' gracias a estas fundas de almohada de seda que cuestan tan solo $ 10

Miles de compradores de Amazon recomiendan la funda de almohada de seda Mulberry, y está a la venta en este momento. La funda de almohada de seda viene en varios colores y ayuda a mantener el cabello suave y la piel clara. Compre las fundas de almohada de seda mientras tienen hasta un 46 por ciento de descuento en Amazon

Se busca al corredor de los Bengals Joe Mixon por orden de arresto emitida por presuntamente apuntar con un arma de fuego a una mujer

Se busca al corredor de los Bengals Joe Mixon por orden de arresto emitida por presuntamente apuntar con un arma de fuego a una mujer

El jueves se presentó una denuncia de delito menor amenazante agravado contra Joe Mixon.

Profesor de la Universidad de Purdue arrestado por presuntamente traficar metanfetamina y proponer favores sexuales a mujeres

Profesor de la Universidad de Purdue arrestado por presuntamente traficar metanfetamina y proponer favores sexuales a mujeres

El Departamento de Policía de Lafayette comenzó a investigar a un profesor de la Universidad de Purdue en diciembre después de recibir varias denuncias de un "hombre sospechoso que se acercaba a una mujer".

Concept Drift: el mundo está cambiando demasiado rápido para la IA

Concept Drift: el mundo está cambiando demasiado rápido para la IA

Al igual que el mundo que nos rodea, el lenguaje siempre está cambiando. Mientras que en eras anteriores los cambios en el idioma ocurrían durante años o incluso décadas, ahora pueden ocurrir en cuestión de días o incluso horas.

India me está pateando el culo

India me está pateando el culo

Estoy de vuelta por primera vez en seis años. No puedo decirte cuánto tiempo he estado esperando esto.

ℝ

“And a river went out of Eden to water the garden, and from thence it was parted and became into four heads” Genesis 2:10. ? The heart is located in the middle of the thoracic cavity, pointing eastward.

¿Merrick Garland le ha fallado a Estados Unidos?

Es más de la mitad de la presidencia de Biden. ¿Qué está esperando Merrick Garland?

¿Merrick Garland le ha fallado a Estados Unidos?

Creo, un poco tarde en la vida, en dar oportunidades a la gente. Generosamente.

Language