python - Cómo importar un módulo desde un directorio en el nivel por encima del script actual
gchart (5)
Para mi aplicación Python, tengo la siguiente estructura de directorios:
/myapp
/myapp/utils/
/myapp/utils/GChartWrapper/
/myapp/model/
/myapp/view/
/myapp/controller/
Uno de mi clase en / myapp / view / debe importar una clase llamada GChartWrapper . Sin embargo, recibo un error de importación ...
myview.py
from myapp.utils.GChartWrapper import *
Aquí está el error:
<type ''exceptions.ImportError''>: No module named GChartWrapper.GChart
args = (''No module named GChartWrapper.GChart'',)
message = ''No module named GChartWrapper.GChart''
¿Qué estoy haciendo mal? Realmente me cuesta mucho importar módulos / clases en Python ...
El archivo __init__.py del paquete GChartWrapper espera el paquete GChartWrapper en PYTHONPATH. Puedes ver por la primera línea:
from GChartWrapper.GChart import *
¿Es necesario tener el paquete GChartWrapper incluido en la estructura del directorio de su paquete? Si es así, entonces una cosa que podría hacer es agregar la ruta donde reside el paquete a sys.path en tiempo de ejecución. Supongo que myview.py
está en el directorio myapp/view
? Entonces podrías hacer esto antes de importar GChartWrapper
:
import sys
import os
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), ''..'', ''utils'')))
Si no es necesario tenerlo en la estructura de su directorio, podría ser más fácil tenerlo instalado en la ubicación convencional. Puede hacerlo ejecutando el script setup.py que se incluye en la distribución fuente GChartWrapper.
No importa módulos y paquetes desde rutas arbritarias. En cambio, en python usa paquetes e importaciones absolutas. Eso evitará todos los problemas futuros.
Ejemplo:
crea los siguientes archivos:
MyApp/myapp/__init__.py
MyApp/myapp/utils/__init__.py
MyApp/myapp/utils/charts.py
MyApp/myapp/model/__init__.py
MyApp/myapp/view/__init__.py
MyApp/myapp/controller/__init__.py
MyApp/run.py
MyApp/setup.py
MyApp/README
Los archivos deben estar vacíos a excepción de aquellos:
MyApp/myapp/utils/charts.py:
class GChartWrapper(object):
def __init__(self):
print "DEBUG: An instance of GChartWrapper is being created!"
MyApp/myapp/view/__init__.py:
from myapp.utils.charts import GChartWrapper
def start():
c = GChartWrapper() # creating instance of the class
MyApp/run.py:
from myapp.view import start
start()
¡Eso es todo! Cuando ejecuta su punto de entrada ( run.py
) llama a una función en la vista, y eso crea una instancia de la clase GChartWrapper. Usando esta estructura puedes importar cualquier cosa en cualquier lugar y usarla.
Para complementar, en MyApp/setup.py
escribe un programa de instalación para el paquete MyApp / myapp. Use distutils para escribirlo:
from distutils.core import setup
setup(name=''MyApp'',
version=''1.0'',
description=''My Beautiful Application'',
author=''Martin'',
author_email=''[email protected]'',
url=''http://.com/questions/1003843/'',
packages=[''myapp''],
scripts=[''run.py'']
)
Es suficiente. Ahora, cuando las personas descargan la carpeta MyApp, pueden instalarla usando setup.py y ejecutarla usando run.py. Distutils puede generar paquetes en varios formatos, incluido Windows instalable .EXE
Es la forma estándar de distribución de paquetes / aplicaciones de Python.
O comenzando en python 2.5 (nuevamente suponiendo que myview está en myapp / view:
from __future__ import absolute_import
from ..utils.GChartWrapper import *
Ver: http://docs.python.org/whatsnew/2.5.html#pep-328-absolute-and-relative-imports
Puede cambiar la ruta donde python busca los archivos.
En la parte superior de tu archivo fuente, agrega:
import sys
sys.path.append("..")
O alternativamente cambie la variable de entorno:
export PYTHONPATH=..
GChartWrapper también está disponible en PyPI para que puedas usar easy_install o pip para instalar el módulo:
sudo pip install GChartWrapper==0.9
Luego se agregará automáticamente a su PYTHONPATH y luego podrá eliminarlo de su directorio / myapp / utils. Si no puede usar sudo, mire usando virtualenv (y virtualenvwrapper).