Pregunta Importar un módulo desde una ruta relativa


¿Cómo importo un módulo de Python dada su ruta relativa?

Por ejemplo, si dirFoo contiene Foo.py y dirBary dirBar contiene Bar.py¿Cómo importo? Bar.py dentro Foo.py?

Aquí hay una representación visual:

dirFoo\
    Foo.py
    dirBar\
        Bar.py

Foo desea incluir Bar, pero la reestructuración de la jerarquía de carpetas no es una opción.


703
2017-11-10 21:28


origen


Respuestas:


Asumiendo que ambos directorios son paquetes reales de Python (tienen el __init__.py archivo dentro de ellos), aquí hay una solución segura para la inclusión de módulos en relación con la ubicación del script.

Supongo que quiere hacer esto, porque necesita incluir un conjunto de módulos con su secuencia de comandos. Lo uso en producción en varios productos y funciona en muchos escenarios especiales, como: scripts llamados desde otro directorio o ejecutados con python en lugar de abrir un nuevo intérprete.

 import os, sys, inspect
 # realpath() will make your script run, even if you symlink it :)
 cmd_folder = os.path.realpath(os.path.abspath(os.path.split(inspect.getfile( inspect.currentframe() ))[0]))
 if cmd_folder not in sys.path:
     sys.path.insert(0, cmd_folder)

 # Use this if you want to include modules from a subfolder
 cmd_subfolder = os.path.realpath(os.path.abspath(os.path.join(os.path.split(inspect.getfile( inspect.currentframe() ))[0],"subfolder")))
 if cmd_subfolder not in sys.path:
     sys.path.insert(0, cmd_subfolder)

 # Info:
 # cmd_folder = os.path.dirname(os.path.abspath(__file__)) # DO NOT USE __file__ !!!
 # __file__ fails if the script is called in different ways on Windows.
 # __file__ fails if someone does os.chdir() before.
 # sys.argv[0] also fails, because it doesn't not always contains the path.

Como beneficio adicional, este enfoque le permite forzar a Python a usar su módulo en lugar de los instalados en el sistema.

¡Advertencia! Realmente no sé lo que está sucediendo cuando el módulo actual está dentro de un egg archivo. Probablemente falla también.


312
2018-05-23 14:00



Asegúrese de que dirBar tenga el __init__.py archivo: esto convierte un directorio en un paquete de Python.


316
2017-11-10 21:33



También podría agregar el subdirectorio a su ruta de Python para que importe como una secuencia de comandos normal.

import sys
sys.path.insert(0, <path to dirFoo>)
import Bar

245
2017-11-10 22:04



import os
import sys
lib_path = os.path.abspath(os.path.join(__file__, '..', '..', '..', 'lib'))
sys.path.append(lib_path)

import mymodule

109
2017-11-26 10:21



Simplemente haga cosas simples para importar el archivo .py de una carpeta diferente.

Digamos que tienes un directorio como:

lib/abc.py

Luego solo mantenga un archivo vacío en la carpeta lib como se

__init__.py

Y luego usa

from lib.abc import <Your Module name>

Mantener el __init__.py archivo en cada carpeta de la jerarquía del módulo de importación.


94
2017-12-09 10:40



Si estructuras tu proyecto de esta manera:

src\
  __init__.py
  main.py
  dirFoo\
    __init__.py
    Foo.py
  dirBar\
    __init__.py
    Bar.py

Luego, desde Foo.py deberías poder hacer:

import dirFoo.Foo

O:

from dirFoo.Foo import FooObject

Por el comentario de Tom, esto requiere que el src la carpeta es accesible a través de site_packages o su ruta de búsqueda. Además, como él menciona, __init__.py se importa implícitamente cuando primero importa un módulo en ese paquete / directorio. Típicamente __init__.py es simplemente un archivo vacío.


77
2017-11-10 21:46



El método más fácil es usar sys.path.append ().

Sin embargo, también puede estar interesado en el diablillo módulo. Proporciona acceso a funciones de importación internas.

# mod_name is the filename without the .py/.pyc extention
py_mod = imp.load_source(mod_name,filename_path) # Loads .py file
py_mod = imp.load_compiled(mod_name,filename_path) # Loads .pyc file 

Esto se puede usar para cargar módulos dinámicamente cuando no se conoce el nombre de un módulo.

Lo he usado en el pasado para crear una interfaz tipo plugin para una aplicación, donde el usuario escribía una secuencia de comandos con funciones específicas de la aplicación, y simplemente soltaba la secuencia de comandos en un directorio específico.

Además, estas funciones pueden ser útiles:

imp.find_module(name[, path])
imp.load_module(name, file, pathname, description)

44
2017-11-12 01:56



Esta es la PEP relevante:

http://www.python.org/dev/peps/pep-0328/

En particular, suponiendo que dirFoo es un directorio desde dirBar ...

En dirFoo \ Foo.py:

from ..dirBar import Bar

40
2017-11-10 22:22