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
pkg
contiene los submódulospkg.main
ypkg.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 comopkg.string
módulo y ese módulo está vinculado al nombre"string"
en elpkg.main
espacio de nombres del módulo.
Así que creé esta estructura de directorio exacta:
$ ls -R
.:
pkg/
./pkg:
__init__.py main.py string.py
__init__.py
y string.py
están vacíos. main.py
contiene 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
import
el comportamiento a importaciones absolutas usando unafrom __future__ import absolute_import
directiva. 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 string
siempre encontrará la versión de la biblioteca estándar.
Creé así pkg/main2.py
, idéntico main.py
pero 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 string
será 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 print
declaració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 string
que 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 pkg
e 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?
El registro de cambios está redactado de manera descuidada. from __future__ import absolute_import
no le importa si algo es parte de la biblioteca estándar y import string
no siempre le dará el módulo de biblioteca estándar con importaciones absolutas activadas.
from __future__ import absolute_import
significa que si usted import string
, Python siempre buscará un string
mó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 string
módulo. Cuando tu lo hagas
python pkg/script.py
pkg/script.py
no parece parte de un paquete para Python. Siguiendo los procedimientos normales, el pkg
directorio se agrega a la ruta y todos los .py
archivos en el pkg
directorio se ven como módulos de nivel superior. import string
encuentra pkg/string.py
no porque esté haciendo una importación relativa, sino porque pkg/string.py
parece ser el módulo de nivel superior string
. string
No surge el hecho de que este no es el módulo de biblioteca estándar .
Para ejecutar el archivo como parte del pkg
paquete, puede hacer
python -m pkg.script
En este caso, el pkg
directorio 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.py
que Python lo trate como parte del pkg
paquete 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 pkg
directorio de la ruta, y si pkg
el directorio principal no está en la ruta, deberá pegarlo también en la ruta.
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.py
tiene un comportamiento diferente al iniciar python2
y luego importar pkg.main2
(que es equivalente a usar el -m
conmutador).
Si alguna vez desea ejecutar un submódulo de un paquete, utilice siempre el -m
conmutador que evita que el intérprete encamine la sys.path
lista 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.
La estrella de HGTV, Christina Hall, revela que le diagnosticaron envenenamiento por mercurio y plomo, probablemente debido a su trabajo como manipuladora de casas.
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.
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.
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 inodoros arrojan columnas de aerosol invisibles con cada descarga. ¿Como sabemos? La prueba fue capturada por láseres de alta potencia.
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?
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!
¿Sigue siendo efectivo ese lote de repelente de insectos que te quedó del verano pasado? Si es así, ¿por cuánto tiempo?
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.
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”.
¿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.
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.
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.
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
El jueves se presentó una denuncia de delito menor amenazante agravado contra Joe Mixon.
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".
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.
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.
Creo, un poco tarde en la vida, en dar oportunidades a la gente. Generosamente.