Se recomienda no usar import *
en Python.
¿Alguien puede compartir la razón de eso, para evitar que lo haga la próxima vez?
import *
no funciona para mí en primer lugar en Python 2 o 3.
Se recomienda no usar import *
en Python.
¿Alguien puede compartir la razón de eso, para evitar que lo haga la próxima vez?
import *
no funciona para mí en primer lugar en Python 2 o 3.
Respuestas:
Debido a que pone muchas cosas en su espacio de nombres (podría ocultar algún otro objeto de la importación anterior y no lo sabrá).
Porque no sabe exactamente qué se importa y no puede encontrar fácilmente desde qué módulo se importó una determinada cosa (legibilidad).
Porque no puedes usar herramientas geniales como pyflakes
detectar estáticamente errores en tu código.
numpy.any
sombreado any
cuando lo hacen from numpy import *
o una herramienta "útil" lo hace por ellos.
import *
hace que el orden de las import
declaraciones sea significativo ... incluso para los módulos de biblioteca estándar que normalmente no se preocupan por el orden de importación . Algo tan inocente como alfabetizar sus import
declaraciones podría romper su guión cuando una víctima anterior de la guerra de importación se convierte en el único sobreviviente. (Incluso si su script funciona ahora y nunca cambia, podría fallar repentinamente algún tiempo después si el módulo importado introduce un nuevo nombre que reemplaza al que confiaba).
De acuerdo con el Zen de Python :
Explícito es mejor que implícito.
... no se puede discutir con eso, ¿verdad?
use strict
(JavaScript var
). Por otro lado, por supuesto, Python no es sin tipo (de hecho, está fuertemente tipado). De todos modos, incluso si tuviera razón, esto todavía contradiría el Zen de Python, citado en esta respuesta.
No pasas **locals()
a las funciones, ¿verdad?
Dado que Python carece de una declaración de "inclusión", y el self
parámetro es explícito, y las reglas de alcance son bastante simples, generalmente es muy fácil señalar con el dedo una variable y decir de dónde proviene ese objeto, sin leer otros módulos y sin ningún tipo de IDE (que están limitadas en la forma de introspección de todos modos, por el hecho de que el lenguaje es muy dinámico).
El import *
rompe todo eso.
Además, tiene una posibilidad concreta de ocultar errores.
import os, sys, foo, sqlalchemy, mystuff
from bar import *
Ahora, si el módulo de barra tiene alguno de los atributos " os
", " mystuff
", etc., anulará los importados explícitamente y posiblemente apuntará a cosas muy diferentes. La definición __all__
en la barra a menudo es sabia, esto indica lo que se importará implícitamente, pero aún así es difícil rastrear de dónde provienen los objetos, sin leer y analizar el módulo de barra y seguir sus importaciones. Una red de import *
es lo primero que soluciono cuando tomo posesión de un proyecto.
No me malinterpreten: si import *
faltaran, lloraría por tenerlo. Pero tiene que ser usado con cuidado. Un buen caso de uso es proporcionar una interfaz de fachada sobre otro módulo. Del mismo modo, el uso de declaraciones de importación condicionales, o importaciones dentro de espacios de nombres de función / clase, requiere un poco de disciplina.
Creo que en proyectos medianos a grandes, o pequeños con varios contribuyentes, se necesita un mínimo de higiene en términos de análisis estático, ejecutando al menos pyflakes o incluso mejor un pylint configurado correctamente, para detectar varios tipos de errores antes Ellos pasan.
Por supuesto, dado que esto es python, siéntase libre de romper las reglas y explorar, pero tenga cuidado con los proyectos que podrían multiplicarse por diez, si el código fuente no tiene disciplina, será un problema.
execfile()
. Afortunadamente, rara vez se usa y desaparece en 3.x.
**vars()
incluimos globales si la función llamada está en otro archivo? : P
Eso es porque estás contaminando el espacio de nombres. Importará todas las funciones y clases en su propio espacio de nombres, lo que puede chocar con las funciones que usted mismo defina.
Además, creo que usar un nombre calificado es más claro para la tarea de mantenimiento; puede ver en la línea de código de dónde proviene una función, por lo que puede consultar los documentos con mucha más facilidad.
En el módulo foo:
def myFunc():
print 1
En su código:
from foo import *
def doThis():
myFunc() # Which myFunc is called?
def myFunc():
print 2
http://docs.python.org/tutorial/modules.html
Tenga en cuenta que, en general, la práctica de importar
*
desde un módulo o paquete está mal vista, ya que a menudo causa un código poco legible .
Digamos que tiene el siguiente código en un módulo llamado foo:
import ElementTree as etree
y luego en tu propio módulo tienes:
from lxml import etree
from foo import *
Ahora tiene un módulo difícil de depurar que parece que tiene etree de lxml, pero realmente tiene ElementTree en su lugar.
Estas son todas buenas respuestas. Voy a agregar que cuando enseño a nuevas personas a codificar en Python, lidiar con esto import *
es muy difícil. Incluso si usted o ellos no escribieron el código, sigue siendo un obstáculo.
Enseño a niños (alrededor de 8 años) a programar en Python para manipular Minecraft. Me gusta darles un entorno de codificación útil para trabajar ( Atom Editor ) y enseñarles el desarrollo impulsado por REPL (a través de bpython ). En Atom, encuentro que las sugerencias / finalización funcionan tan efectivamente como bpython. Afortunadamente, a diferencia de otras herramientas de análisis estadístico, Atom no se deja engañar import *
.
Sin embargo, tomemos este ejemplo ... En este contenedor , hay from local_module import *
un montón de módulos que incluyen esta lista de bloques . Ignoremos el riesgo de colisiones en el espacio de nombres. Al hacerlo from mcpi.block import *
, hacen que esta lista completa de tipos oscuros de bloques sea algo que debe mirar para saber qué hay disponible. Si en su lugar lo hubieran usado from mcpi import block
, podría escribir walls = block.
y luego aparecería una lista de autocompletar.
Entendido los puntos válidos que la gente pone aquí. Sin embargo, tengo un argumento que, a veces, "importar estrellas" no siempre es una mala práctica:
const.py
:
import const
, entonces, para cada constante, tengo que referirme a esto const.SOMETHING
, lo que probablemente no sea la forma más conveniente.from const import SOMETHING_A, SOMETHING_B ...
, entonces obviamente es demasiado detallado y frustra el propósito de la estructuración.from const import *
puede ser una mejor opción.Es una práctica muy MALA por dos razones:
Para el punto 1 : Veamos un ejemplo de esto:
from module1 import *
from module2 import *
from module3 import *
a = b + c - d
Aquí, al ver el código, nadie tendrá idea de qué módulo b
, c
y en d
realidad pertenece.
Por otro lado, si lo haces así:
# v v will know that these are from module1
from module1 import b, c # way 1
import module2 # way 2
a = b + c - module2.d
# ^ will know it is from module2
Es mucho más limpio para usted, y también la nueva persona que se una a su equipo tendrá una mejor idea.
Para el punto 2 : Digamos ambos module1
y module2
tengamos una variable como b
. Cuando lo hago:
from module1 import *
from module2 import *
print b # will print the value from module2
Aquí module1
se pierde el valor de . Será difícil depurar por qué el código no funciona, incluso si b
está declarado module1
y he escrito el código esperando que mi código usemodule1.b
Si tiene las mismas variables en diferentes módulos y no desea importar el módulo completo, incluso puede hacer lo siguiente:
from module1 import b as mod1b
from module2 import b as mod2b
Como prueba, creé un módulo test.py con 2 funciones A y B, que imprimen respectivamente "A 1" y "B 1". Después de importar test.py con:
import test
. . . Puedo ejecutar las 2 funciones como test.A () y test.B (), y "test" aparece como un módulo en el espacio de nombres, así que si edito test.py, puedo volver a cargarlo con:
import importlib
importlib.reload(test)
Pero si hago lo siguiente:
from test import *
no hay referencia a "prueba" en el espacio de nombres, por lo que no hay forma de volver a cargarlo después de una edición (por lo que puedo decir), lo cual es un problema en una sesión interactiva. Considerando que cualquiera de los siguientes:
import test
import test as tt
agregará "prueba" o "tt" (respectivamente) como nombres de módulo en el espacio de nombres, lo que permitirá volver a cargar.
Si lo hago:
from test import *
los nombres "A" y "B" aparecen en el espacio de nombres como funciones . Si edito test.py y repito el comando anterior, las versiones modificadas de las funciones no se vuelven a cargar.
Y el siguiente comando genera un mensaje de error.
importlib.reload(test) # Error - name 'test' is not defined
Si alguien sabe cómo volver a cargar un módulo cargado con "from module import *", publique. De lo contrario, esta sería otra razón para evitar el formulario:
from module import *
Como se sugiere en los documentos, (casi) nunca debe usar import *
en el código de producción.
Si bien la importación *
desde un módulo es mala, la importación * desde un paquete es aún peor. De manera predeterminada, from package import *
importa los nombres definidos por el paquete __init__.py
, incluidos los submódulos del paquete que se cargaron en import
declaraciones anteriores .
Sin embargo, si el __init__.py
código de un paquete define una lista llamada __all__
, se considera que es la lista de nombres de submódulos que deben importarse cuando from package import *
se encuentra.
Considere este ejemplo (suponiendo que no haya __all__
definido en sound/effects/__init__.py
):
# anywhere in the code before import *
import sound.effects.echo
import sound.effects.surround
# in your module
from sound.effects import *
La última instrucción importará los módulos echo
y surround
en el espacio de nombres actual (posiblemente anulando las definiciones anteriores) porque se definen en el sound.effects
paquete cuando import
se ejecuta la instrucción.