Situación: - Hay un módulo en mi carpeta_proyecto llamado calendario - Me gustaría usar la clase Calendario incorporada de las bibliotecas de Python - Cuando utilizo Calendario de importación de calendario, se queja porque está intentando cargar desde mi módulo.
He hecho algunas búsquedas y parece que no puedo encontrar una solución a mi problema.
- ¿Cómo acceder a un módulo de biblioteca estándar en Python cuando hay un módulo local con el mismo nombre?
- http://docs.python.org/whatsnew/2.5.html
- ¿Cómo evitar escribir el nombre del módulo todo el tiempo al importar un módulo en Python?
¿Alguna idea sin tener que cambiar el nombre de mi módulo?
Respuestas:
La solución aceptada contiene un enfoque ahora obsoleto.
La documentación de importlib aquí da un buen ejemplo de la forma más apropiada de cargar un módulo directamente desde una ruta de archivo para python> = 3.5:
Por lo tanto, puede cargar cualquier archivo .py desde una ruta y configurar el nombre del módulo para que sea el que desee. Así que ajusta el
module_name
para que sea el nombre personalizado que le gustaría que tuviera el módulo al importar.Para cargar un paquete en lugar de un solo archivo,
file_path
debe ser la ruta a la raíz del paquete__init__.py
fuente
file_path=r"C:\Users\My User\My Path\Module File.py"
. Luego llamémodule_name
como el módulo publicado para tener un script de trabajo completo que, eliminado de este fragmento, podría usarse en otras PCNo es necesario cambiar el nombre de su módulo. Por el contrario, puede utilizar absolute_import para cambiar el comportamiento de importación. Por ejemplo, con stem / socket.py importo el módulo de socket de la siguiente manera:
Esto solo funciona con Python 2.5 y superior; está habilitando el comportamiento que es el predeterminado en Python 3.0 y superior. Pylint se quejará del código pero es perfectamente válido.
fuente
PYTHONPATH
. Otra pregunta muestra cómo resolver eso.En realidad, resolver esto es bastante fácil, pero la implementación siempre será un poco frágil, porque depende de los componentes internos del mecanismo de importación de Python y están sujetos a cambios en futuras versiones.
(el siguiente código muestra cómo cargar módulos locales y no locales y cómo pueden coexistir)
La mejor solución, si es posible, es evitar nombrar sus módulos con el mismo nombre que la biblioteca estándar o los nombres de los módulos integrados.
fuente
sys.modules
los intentos posteriores de cargar el módulo local?La única forma de resolver este problema es secuestrar usted mismo la maquinaria de importación interna. Esto no es fácil y está plagado de peligros. Debe evitar la baliza en forma de grial a toda costa porque el peligro es demasiado peligroso.
En su lugar, cambie el nombre de su módulo.
Si desea aprender cómo secuestrar la maquinaria de importación interna, aquí es donde puede averiguar cómo hacerlo:
A veces hay buenas razones para correr este peligro. La razón que das no está entre ellos. Cambie el nombre de su módulo.
Si toma la ruta peligrosa, un problema que encontrará es que cuando carga un módulo, termina con un 'nombre oficial' para que Python pueda evitar tener que analizar el contenido de ese módulo nunca más. Se puede encontrar una asignación del 'nombre oficial' de un módulo al objeto del módulo en sí
sys.modules
.Esto significa que si está
import calendar
en un lugar, cualquier módulo que se importe se considerará como el módulo con el nombre oficialcalendar
y todos los demás intentos enimport calendar
cualquier otro lugar, incluso en otro código que forma parte de la biblioteca principal de Python, obtendrán ese calendario.Podría ser posible diseñar un importador de clientes utilizando el módulo imputil en Python 2.x que provocó que los módulos cargados desde ciertas rutas buscaran los módulos que estaban importando en algo diferente a
sys.modules
primero o algo así. Pero eso es algo extremadamente complicado y no funcionará en Python 3.x de todos modos.Hay algo extremadamente feo y horrible que puede hacer que no implica enganchar el mecanismo de importación. Esto es algo que probablemente no debería hacer, pero probablemente funcionará. Convierte su
calendar
módulo en un híbrido del módulo de calendario del sistema y su módulo de calendario. Gracias a Boaz Yaniv por el esqueleto de la función que utilizo . Pon esto al principio de tucalendar.py
archivo:fuente
code
módulo std de Python ), lo que significa que solo una fracción de los desarrolladores podría tener algún problema con este "truco de fusión". Los usuarios no se verían afectados en absoluto.Me gustaría ofrecer mi versión, que es una combinación de la solución de Boaz Yaniv y Omnifarious. Importará la versión del sistema de un módulo, con dos diferencias principales con respecto a las respuestas anteriores:
Ponga esto en algún lugar accesible para que pueda llamarlo (tengo el mío en mi archivo __init__.py):
Ejemplo
Quería importar mysql.connection, pero ya tenía un paquete local llamado mysql (las utilidades oficiales de mysql). Entonces, para obtener el conector del paquete mysql del sistema, reemplacé esto:
Con este:
Resultado
fuente
Cambie la ruta de importación:
fuente
sys.modules
y no volverá a importar un módulo con el mismo nombre.