Por lo general, veo este patrón al menos una vez en cada proyecto de Python en el que trabajo. Por ejemplo, en un proyecto Django, esto a menudo se agrega al final del archivo de configuración base:
try:
from .local_settings import *
except ImportError:
pass
También:
try:
import simplejson as json
except ImportError:
import json
Sin embargo, esto siempre me ha molestado un poco; ¿Qué pasa si el módulo se importa con éxito, pero luego se dispara ImportError
? Por ejemplo, en el primer ejemplo, el local_settings
módulo existe, pero luego local_settings
trata de importar un módulo inexistente.
¿Es esta la forma más segura de importar un módulo opcional, hay una mejor manera de lograr esta funcionalidad, o depende del contexto / uso (y si es así, ¿cuáles son las pautas para decidir cuándo usar este enfoque)?
ImportWarning
sugiere la documentación .Esto generalmente es seguro, suponiendo que sus módulos estén libres de efectos secundarios de tiempo de importación.
Si un módulo importado genera alguna excepción (no solo
ImportError
) en el momento de la importación, se elimina desys.modules
. Esto significa que si algún otro código intenta importar el módulo, no obtendrá un módulo parcialmente inicializado. En cambio, Python intentará cargar el módulo nuevamente, y presumiblemente fallaráImportError
nuevamente.Esto puede causar problemas si sus módulos tienen efectos secundarios de tiempo de importación, ya que esos efectos no se deshacen. En particular, si el módulo infractor importa con éxito otro módulo, este último no se elimina
sys.modules
. Este efecto secundario en particular rara vez es un problema, pero algunos efectos secundarios pueden ser más problemáticos.fuente