2013-11-14 3 views
6

Учитывая следующий проект питона, созданный в PyDev:Python не Finding модуль

├── algorithms 
│   ├── __init__.py 
│   └── neighborhood 
│    ├── __init__.py 
│    ├── neighbor 
│    │   ├── connector.py 
│    │   ├── __init__.py 
│    │   ├── manager.py 
│    │   └── references.py 
│    ├── neighborhood.py 
│    ├── tests 
│    │   ├── fixtures 
│    │   │   └── neighborhood 
│    │   ├── __init__.py 
│    └── web 
│     ├── __init__.py 
│     └── service.py 
├── configuration 
│   ├── Config.py 
│   └── __init__.py 
├── __init__.py 
└── webtrack 
    |- teste.py 
    ├── .gitignore 
    ├── __init__.py 
    ├── manager 
       ├── Data.py 
       ├── ImportFile.py 
       └── __init__.py 

Мы пытались, но безуспешно, чтобы импортировать модули из одной папки в другую, например:

from algorithms.neighborhood.neighbor.connector import NeighborhoodConnector 

Который дает результат:

Traceback (most recent call last): 
File "teste.py", line 49, in <module> 
from algorithms.neighborhood.neighbor.connector import NeighborhoodConnector 
ImportError: No module named algorithms.neighborhood.neighbor.connector 

Мы пытались добавить свой путь к переменной sys.path, но без успеха ,

Мы также пытались использовать os.walk для вставки всех путей в переменную PATH, но при этом мы получаем ту же ошибку, хотя мы проверили, что PATH содержит путь для поиска модулей.

Мы используем Python 2.7 на Linux Ubuntu 13.10.

Есть ли что-нибудь, что мы можем делать неправильно?

Спасибо заранее,

+0

Вы проверили, насколько далеко по цепочке импорта возникла проблема?То есть, 'import algorithmms.neighborhood.neighbor.connector' терпит неудачу? Что относительно 'import algorithmms.neighborhood.neighbor',' import algorithmms.neighborhood' и 'import algorithms'? – BrenBarn

+0

Python 2 или Python 3? –

+0

@BrenBarn Мы попытались предложить вам такую ​​же ошибку. –

ответ

0

Путь импорта работать немного отличается в Python 2 и 3. Первый Python 3 и разумный способ (который вы, кажется, ожидать). В Python 3 все импорты относятся к папкам в sys.path (see here для получения дополнительной информации о пути поиска модуля). Кстати, Python не использует $PATH.

Таким образом, вы можете импортировать что угодно из любого места, не беспокоясь слишком много.

В Python 2 импорт относительный, а иногда и абсолютный. document about packages содержит пример макета и некоторые операторы импорта, которые могут быть вам полезны.

Раздел «Intra-package References» содержит информацию о том, как импортировать между пакетами.

Из-за вышеизложенного, я думаю, что ваш sys.path неправ. Убедитесь, что папка, которая содержит algorithms (т.е. неalgorithms себя, но это родитель) должен быть в sys.path

+0

Попытка вставить в teste.py строку 'from ..algorithms.neighborhood.neighbor.connector import NeighborhoodConnector' вывел ошибку: ValueError: Попытка относительного импорта в не-пакет. Что-то не так? Все файлы __init__.py присутствуют –

+0

Это действительно странно. 1. Вы можете отлаживать импорт, который работает с 'python -v', но не те, которые терпят неудачу. Попробуйте это в любом случае. 2. Может быть, есть опечатка в одном из файлов '__init __. Py'? 3. Еще раз проверьте, что 'sys.path' содержит правильные значения. Возможно, попробуйте загрузить модуль вручную: http://docs.python.org/2/library/importlib.html#importlib.import_module –

3

Получение импорта прямо при запуске сценария, который живет в пакет сложно. Вы можете прочитать this section of the (sadly deferred) PEP 395 для описания нескольких способов, которые не работают для запуска такого скрипта.

Дайте иерархии файловой системы, как:

top_level/ 
    my_package/ 
     __init__.py 
     sub_package/ 
      __init__.py 
      module_a.py 
      module_b.py 
      sub_sub_package/ 
       __init__.py 
       module_c.py 
     scripts/ 
      __init__.py 
      my_script.py 
      script_subpackage/ 
       __init__.py 
       script_module.py 

Есть только несколько способов, чтобы сделать работает my_script.py работать правильно.

  1. Первое будет положить папку top_level в переменном в PYTHONPATH среды, или использовать .pth файл для достижения того же. Или, как только интерпретатор будет запущен, вставьте эту папку в sys.path (но это может стать уродливым).

    Обратите внимание, что вы добавляете top_level на путь, а не my_package!Я подозреваю, что это то, что вы перепутали в своих текущих попытках этого решения. Его очень легко ошибиться.

    Тогда абсолютный импорт, как import my_package.sub_package.module_a, будет в основном работать правильно. (Только не пытайтесь импортировать package.scripts.my_script себя в то время как он работает, как __main__ модуля, или вы получите странный дубликат модуля.)

    Однако абсолютный импорт всегда будет более многословным, чем относительно импорта, так как вам всегда нужно указывать полный путь, даже если вы импортируете модуль (или «племянник»), например module_c от module_a). При абсолютном импорте способ получить module_c всегда является большим, уродливым глотком кода from my_package.sub_package.sub_sub_package import module_c независимо от того, какой модуль выполняет импорт.

  2. По этой причине использование относительного импорта часто является более элегантным. Увы, им трудно работать от скрипта. Единственными способами являются:

    1. Run my_script из top_level папки с -m флагом (например python -m my_package.scripts.my_script) и никогда по имени файла.

      Он не будет работать, если вы находитесь в другой папке, или если вы используете другой метод для запуска сценария (например, нажатие F5 в среде IDE). Это несколько негибко, но на самом деле нет способа облегчить его (пока PEP 395 не будет отменен и не будет реализован).

    2. Настройка sys.path как для абсолютного импорта (например, добавление top_level к PYTHONPATH или что-то), а затем использовать PEP 366__package__ строки сказать Python, что ожидаемый пакет вашего сценария. То есть, в my_script.py вы хотели бы поставить что-то вроде этого, прежде всего, Ваш родственник импорт:

      if __name__ == "__main__" and __package__ is None: 
          __package__ = "my_package.my_scripts" 
      

      Это потребует обновления, если вы реорганизовать организацию файлов и переместить сценарий в другой пакет (но это, вероятно, меньше, работать, чем обновлять партии абсолютного импорта).

    Как только вы внедрили один из этих правил, ваш импорт может стать проще. Импорт module_c от module_a становится from .sub_sub_package import module_c. В my_script относительный импорт, как from ..subpackage import module_a, просто будет работать.

0

Просто установите __pacage__ = None в каждый .py файла. Он автоматически настроит всю иерархию пакетов.

После этого вы можете свободно использовать абсолютные имена модулей для импорта.

from algorithms.neighborhood.neighbor.connector import NeighborhoodConnector

0

Я знаю, что это старый пост, но все-таки я собираюсь опубликовать свое решение.

Был аналогичный вопрос. Просто добавьте пути со следующей строкой перед импортом пакета:

sys.path.append(os.path.join(os.path.dirname(__file__), '..')) 
from lib import create_graph 
Смежные вопросы