En Python, ¿es una buena práctica importar todos los atributos con un comodín?

¿y por qué?

A veces necesito importar todos los atributos de un módulo, así que uso la importación de comodines, pero uno de mis scripts Vim (usando flake8 como su verificador de syntax) siempre me da una advertencia y me dice que no puedo detectar nombres no definidos.

¿Hay otras desventajas de usar la importación de comodines?

En general, no es una buena idea utilizar from module import * . La importación de comodines conduce a la contaminación del espacio de nombres; importó más nombres de los que necesita y, si accidentalmente hace referencia a un nombre importado, es posible que no obtenga el NameError que deseaba.

Además, si una versión futura de la biblioteca agregó nombres adicionales, podría terminar ocultando otros nombres , lo que provocaría errores aún más extraños:

 from foo import bar from spam import * 

Si actualizas el spam y ahora incluye un spam.bar , reemplazará la importación foo.bar en la línea anterior.

El uso de la importación de comodines puede causar errores sutiles:

foo.py

 import sys os = sys # just for the fun of it... :-D 

consola python

 >>> import os >>> from foo import * >>> os.path.join('p1', 'p2') Traceback (most recent call last): File "", line 1, in  AttributeError: 'list' object has no attribute 'join' 

Esto es especialmente importante al actualizar las versiones de la biblioteca. Pueden o no agregar nuevas variables y romper su código de maneras horribles.

Si realmente desea utilizar la * importación, colóquela primero para que otras importaciones y definiciones tengan prioridad.

Buenas respuestas hasta ahora, pero siempre es bueno referirse a los PyDocs :

Aunque ciertos módulos están diseñados para exportar solo nombres que siguen ciertos patrones cuando se usa importar *, todavía se considera una mala práctica en el código de producción.

Sí, si importas todo usando el comodín, tomas todo de ese paquete y lo conviertes en una instancia en tu script, una mejor manera de hacerlo es simplemente importando el paquete:

ex. paquete de importación

 package.x 

De esta manera no se encontrará con problemas de nombres.

La respuesta de Martijn aborda correctamente el problema de la contaminación del espacio de nombres, pero no creo que ninguna de las respuestas aquí haya abordado correctamente lo que considero el mayor problema … No es explícito .

Considere un módulo hipotético:

 #foo.py from bar import * from baz import * from qux import * def breakfast(x): with corn_beef_hash(x) as yummy: for egg in yummy: yield ham(egg.scrambled) 

Ahora, unos meses más tarde, parece que no puedes recordar lo que realmente hace corn_beef_hash , así que vas a mirar la documentación, excepto que no puedes recordar si corn_beef_hash era parte de bar o baz o qux . Esto hace que sea más difícil de localizar. Además, si sabe dónde se definió originalmente la función, eso le dará algunas pistas sobre lo que se supone que debe hacer, lo que puede facilitar la lectura del código.