Для моего приложения 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...
Ответ 1
__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 script, который включен в дистрибутив GChartWrapper.
Ответ 2
Вы не импортируете модули и пакеты из двоичных путей. Вместо этого в 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. Используйте distutils, чтобы записать его:
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.
Ответ 3
Вы можете изменить путь, в котором python ищет файлы.
В верхней части исходного файла добавьте:
import sys
sys.path.append("..")
Или, альтернативно, измените переменную среды:
export PYTHONPATH=..
Ответ 4
Или начиная с 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-absolute-and-relative-imports
Ответ 5
GChartWrapper также доступен из PyPI, поэтому вы можете использовать easy_install или pip для установки модуля:
sudo pip install GChartWrapper==0.9
Затем он будет автоматически добавлен в ваш PYTHONPATH, а затем вы можете удалить его из каталога /myapp/utils. Если вы не можете использовать sudo, посмотрите на использование virtualenv (и virtualenvwrapper).