Como importar um módulo a partir de um diretório no nível acima do script atual
Pergunta
Para a minha aplicação Python, eu tenho a seguinte estrutura de diretórios:
\myapp
\myapp\utils\
\myapp\utils\GChartWrapper\
\myapp\model\
\myapp\view\
\myapp\controller\
Um dos minha classe em \ myapp \ view \ deve importar uma classe chamada GChartWrapper . No entanto, eu estou recebendo um erro de importação ...
myview.py
from myapp.utils.GChartWrapper import *
Aqui está o erro:
<type 'exceptions.ImportError'>: No module named GChartWrapper.GChart
args = ('No module named GChartWrapper.GChart',)
message = 'No module named GChartWrapper.GChart'
O que estou fazendo de errado? Eu realmente tenho um tempo duro para módulos de importação / classes em Python ...
Solução
O __init__.py
arquivo de o pacote GChartWrapper espera que o pacote de GChartWrapper em PYTHONPATH. Você pode dizer pela primeira linha:
from GChartWrapper.GChart import *
É necessário ter o pacote GChartWrapper em sua estrutura de diretório do pacote?
Se sim, então uma coisa que você poderia fazer é adicionar o caminho onde reside o pacote para sys.path em tempo de execução. Eu levá-la myview.py
está no diretório myapp\view
? Em seguida, você poderia fazer isso antes de importar GChartWrapper
:
import sys
import os
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'utils')))
Se não é necessário tê-lo em sua estrutura de diretório, poderia ser mais fácil de tê-lo instalado no local convencional. Você pode fazer isso executando o script setup.py que está incluído na distribuição fonte GChartWrapper.
Outras dicas
Você não importar módulos e pacotes de caminhos arbritary. Em vez disso, em python você usa pacotes e importações absolutos. Isso vai evitar todos os problemas futuros.
Exemplo:
Criar os seguintes arquivos:
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
Os arquivos devem estar vazio, exceto para aqueles que:
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()
Isso é tudo! Quando você executar o seu ponto de entrada (run.py
) que chama uma função na vista, e que cria uma instância da classe GChartWrapper. Utilizando esta estrutura você pode importar qualquer coisa em qualquer lugar e usá-lo.
Para complementar, em MyApp\setup.py
você escreve um programa de instalação para o MyApp \ pacote myapp. Use distutils para escrevê-lo:
from distutils.core import setup
setup(name='MyApp',
version='1.0',
description='My Beautiful Application',
author='Martin',
author_email='martin@xxxxxxx.com',
url='http://stackoverflow.com/questions/1003843/',
packages=['myapp'],
scripts=['run.py']
)
Isso é o suficiente. Agora quando as pessoas baixar a pasta MyApp, eles podem simplesmente instalá-lo usando setup.py e executá-lo usando run.py. Distutils pode gerar pacotes em uma série de formatos, incluindo janelas instaláveis ??.EXE
É a forma padrão de distribuição de pacotes / aplicações python.
Você pode alterar o caminho onde os olhares python para arquivos.
Na parte superior do seu arquivo de origem, adicione:
import sys
sys.path.append("..")
Ou, alternativamente, alterar a variável de ambiente:
export PYTHONPATH=..
Ou, a partir de 2,5 pitão (novamente assumindo myview é em novaaplicacao \ vista:
from __future__ import absolute_import
from ..utils.GChartWrapper import *
Veja: http: // docs .python.org / whatsnew / 2.5.html # pep-328-absolute-e-relativas-importações
GChartWrapper também está disponível a partir PyPI assim você pode usar easy_install ou pip para instalar o módulo:
sudo pip install GChartWrapper==0.9
Em seguida, será automaticamente adicionado à sua PYTHONPATH e então você pode removê-lo do seu / myapp diretório / utils. Se você não pode usar sudo, olhada com virtualenv (e virtualenvwrapper).