Как импортировать модуль из каталога на уровень выше текущего скрипта
Вопрос
Для моего приложения на Python у меня есть следующая структура каталогов:
\myapp
\myapp\utils\
\myapp\utils\GChartWrapper\
\myapp\model\
\myapp\view\
\myapp\controller\
Один из моих классов в \myapp\view\ должен импортировать класс с именем GChartWrapper ( Обертка для карт ).Однако я получаю сообщение об ошибке импорта...
myview.py
from myapp.utils.GChartWrapper import *
Вот в чем ошибка:
<type 'exceptions.ImportError'>: No module named GChartWrapper.GChart
args = ('No module named GChartWrapper.GChart',)
message = 'No module named GChartWrapper.GChart'
Что я делаю не так?Мне действительно трудно импортировать модули / классы в Python...
Решение
__ init __. py
file пакета GChartWrapper ожидает пакет GChartWrapper в PYTHONPATH. Вы можете сказать по первой строке:
from GChartWrapper.GChart import *
Необходимо ли включать пакет GChartWrapper в структуру каталогов вашего пакета?
Если это так, то вы могли бы добавить путь, по которому пакет находится в sys.path во время выполнения. Я так понимаю, myview.py
находится в каталоге myapp \ view
? Затем вы можете сделать это перед импортом GChartWrapper
:
import sys
import os
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'utils')))
Если нет необходимости иметь его в структуре каталогов, проще установить его в обычном месте. Вы можете сделать это, запустив скрипт setup.py, который включен в исходный дистрибутив GChartWrapper.
Другие советы
Вы не импортируете модули и пакеты из произвольных путей.Вместо этого в python вы используете пакеты и абсолютный импорт.Это позволит избежать всех будущих проблем.
Пример:
создайте следующие файлы:
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
Файлы должны быть пустыми, за исключением тех:
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()
Вот и все!Когда вы запускаете свою точку входа (run.py
) он вызывает функцию в представлении, и это создает экземпляр класса GChartWrapper.Используя эту структуру, вы можете импортировать что угодно в любое место и использовать это.
Дополнять, в MyApp\setup.py
вы пишете программу установки для пакета MyApp\myapp.Использование искажения чтобы написать это:
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']
)
Этого достаточно.Теперь, когда люди загружают папку MyApp, они могут просто установить ее с помощью setup.py и запустить с помощью run.py.Distutils может генерировать пакеты в нескольких форматах, включая устанавливаемый Windows .EXE
Это стандартный способ распространения пакетов / приложений python.
Вы можете изменить путь, по которому python ищет файлы.
В верхней части исходного файла добавьте:
import sys
sys.path.append("..")
Или альтернативно измените переменную среды:
export PYTHONPATH=..
Или начиная с python 2.5 (опять-таки, предположив, что myview находится в myapp \ view:
from __future__ import absolute_import
from ..utils.GChartWrapper import *
См .: http: // docs .python.org / WhatsNew / 2.5.html # PEP-328-абсолютный и относительный-импорт
GChartWrapper также доступен в PyPI, поэтому вы можете использовать easy_install или pip для установки модуля:
sudo pip install GChartWrapper==0.9
Затем он будет автоматически добавлен в вашу PYTHONPATH, а затем вы сможете удалить его из каталога / myapp / utils. Если вы не можете использовать sudo, посмотрите на использование virtualenv (и virtualenvwrapper).