¿Qué importa exactamente "importar *"?

Resuelto ensnare asked hace 14 años • 6 respuestas

En Python, ¿qué importa exactamente import *? ¿Importa lo que __init__.pyse encuentra en la carpeta que lo contiene?

Por ejemplo, ¿es necesario declarar from project.model import __init__o es from project.model import *suficiente?

ensnare avatar Mar 02 '10 10:03 ensnare
Aceptado

La "ventaja" de, from xyz import *a diferencia de otras formas de importación, es que importa todo (bueno, casi... [ver (a) a continuación] todo) desde el módulo designado en el módulo actual. Esto permite utilizar los distintos objetos (variables, clases, métodos...) del módulo importado sin anteponerles el nombre del módulo . Por ejemplo

>>> from math import *
>>>pi
3.141592653589793
>>>sin(pi/2)
>>>1.0

Sin embargo, se desaconseja esta práctica (de importar * al espacio de nombres actual) porque

  • brinda la oportunidad de colisiones de espacios de nombres (por ejemplo, si tenía un nombre de variable pi antes de la importación)
  • puede ser ineficiente si la cantidad de objetos importados es grande
  • no documenta explícitamente el origen de la variable/método/clase (es bueno tener esta "autodocumentación" del programa para futuras visitas al código)

Por lo tanto, normalmente limitamos esta práctica de importación * a pruebas ad hoc y similares. Como señaló @ Denilson-Sá-Maia, algunas bibliotecas como (por ejemplo, pygame) tienen un submódulo donde se definen todas las constantes y funciones más utilizadas y dichos submódulos están diseñados de manera efectiva para importarse con import *. Aparte de estos submódulos especiales, es preferible...:

importar explícitamente solo unos pocos objetos

>>>from math import pi
>>>pi
>>>3.141592653589793
>>> sin(pi/2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'sin' is not defined

o importar el módulo bajo su propio espacio de nombres (o un alias del mismo, en particular si es un nombre largo y el programa hace referencia a sus objetos muchas veces)

  >>>import math
  >>>math.pi
  >>>3.141592653589793
  etc..


  >>>import math as m  #bad example math being so short and standard...
  >>>m.pi
  >>>3.141592653589793
  etc..

Consulte la documentación de Python sobre este tema.

(a) Específicamente, ¿qué se importa con from xyz import *?
si el módulo xyz define una __all__variable, importará todos los nombres definidos en esta secuencia; de lo contrario, importará todos los nombres, excepto aquellos que comiencen con un guión bajo.

Nota Muchas bibliotecas tienen submódulos . Por ejemplo, la biblioteca estándar urllibincluye submódulos como urllib.request, urllib.errorsetc. urllib.responseUn punto común de confusión es que

from urllib import *

importaría todos estos submódulos. Ese NO es el caso : es necesario importarlos explícitamente por separado con, digamos, from urllib.request import *etc. Por cierto, esto no es específico de import *, simple importtampoco importará submódulos (pero, por supuesto, el que a menudo *es una abreviatura de "todo" engañar a la gente haciéndoles creer que todos los submódulos y todo lo demás serían importados).

mjv avatar Mar 02 '2010 03:03 mjv

Importa (al espacio de nombres actual) cualquier nombre que el módulo (o paquete) enumere en su __all__atributo; falta dicho atributo, todos los nombres que no comienzan con _.

Está pensado principalmente como un atajo útil para usar solo en sesiones de intérprete interactivas: como sugieren otras respuestas, no lo use en un programa.

Mi recomendación, según la guía de estilo Python de Google , es importar solo módulos , no clases o funciones (u otros nombres) desde dentro de los módulos. Seguir estrictamente esto genera claridad y precisión, y evita trampas sutiles que pueden surgir al importar "cosas desde dentro de un módulo".

Importar un paquete (o cualquier cosa que esté dentro de él) carga y ejecuta intrínsecamente el paquete __init__.py; ese archivo define el cuerpo del paquete. Sin embargo, no vincula el nombre __init__en su espacio de nombres actual (por lo que, en este sentido, no importa ese nombre).

Alex Martelli avatar Mar 02 '2010 03:03 Alex Martelli