Найти - Пользователи
Полная версия: не импортируется модуль из текущей директории
Начало » Python для новичков » не импортируется модуль из текущей директории
1 2
aCL
Делаю всё по учебнику:
http://habrahabr.ru/post/193242/

Структура папок абсолютно идентичная структуре из учебника, только директория с интерпретатором называется bin, а не flask:

books\
bin\
<файлы виртуального окружения>
app\
static\
templates\
__init__.py
views.py
models.py
forms.py
tmp\
run.py
config.py

В views.py импортирую класс из forms.py:
from forms import Seaker

При запуске “bin\\Scripts\\python run.py” получаю ошибку:
C:\proj\books\bin\Scripts\python.exe C:/proj/books/run.py
Traceback (most recent call last):
  File "C:/proj/books/run.py", line 1, in <module>
    from app import app
  File "C:\proj\books\app\__init__.py", line 9, in <module>
    from app import views, models
  File "C:\proj\books\app\views.py", line 3, in <module>
    from forms import Seaker
ImportError: No module named 'forms'

Аналогично с импортом из models.py

Честно говоря, уже сломал голову. Помогите, пожалуйста.

UPD. При этом при использовании app.model и app.forms всё работает. В чем фишка? Происходит же импорт модуля из текущей директории, для чего необходимо вызывать имя пакета?
py.user.next
Покажи содержимое файлов run.py и __init__.py
FishHook
Так работает?
from app.views import view_func
from app.models import ModelClass
aCL
FishHook
Так работает?
Да, работает. Но почему именно через app, если импорт ведется из текущей директории?

py.user.next
Покажи содержимое файлов run.py и __init__.py
__init__.py:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config.from_object('config')
db = SQLAlchemy(app)
from app import views, models

run.py:
from app import app
if __name__ == '__main__':
    app.run(debug=True)
sander
aCL
потому что импорты работают не так
из app импортируется, потому что импорт идет из пакета “app”, в данном случае из файла __init__.py, куда питон смотрит в первую очередь
aCL
sander
aCLпотому что импорты работают не такиз app импортируется, потому что импорт идет из пакета “app”, в данном случае из файла __init__.py, куда питон смотрит в первую очередь
А куда он смотрит после этого?

сделал такую папку:
app/
__init__.py
module.py
run.py

В __init__.py:
from app import module

В module.py:
a = 'qweqwe'

В run.py:
from module import a
input(a)

запуск run.py выводит вот это самое ‘qweqwe’


В чем разница между ситуацией из первого моего поста и этой? Почему один код работает, а второй нет, хотя, по сути, они идентичны?
aCL
Никто не поможет или никто не знает ответа?
Rodegast
> Но почему именно через app, если импорт ведется из текущей директории?

Ну наверно потому что у тебя текущая директория не app, а books
А вообще прочитай про sys.path и сразу многое станет ясным.
sander
Лутц передает привет
В обеих версиях, Python 3.0 и 2.6, инструкции from теперь могут использовать
точки («.»), чтобы указать, что поиск модулей в первую очередь должен про-изводиться в том же самом пакете (эта особенность известна как импортирование относительно пакета), а не где-то в другом месте, в пути поиска (эта особенность называется импортирование по абсолютному пути). То есть:
• В обеих версиях Python, 3.0 и 2.6, в инструкции fromв начале пути мож-но использовать точки, чтобы указать, что импорт должен производиться
относительновмещающего пакета, – при таком способе импортирования
поиск модулей будет производиться только внутри пакета, а модули с теми
же именами, находящиеся где-то в пути поиска (sys.path), будут недоступны. Благодаря этому модули внутри пакета получают преимущество перед
модулями за его пределами.
• В Python 2.6 обычная операция импортирования в программном коде пакета (без точек) в настоящее время по умолчанию выполняется в порядке
«сначала поиск относительно пакета, потом – абсолютный поиск». То есть
поиск сначала производится в каталоге пакета и только потом в пути поиска. Однако в Python 3.0 по умолчанию выполняется импортирование по абсолютному пути – при отсутствии точек операции импортирования пропускают вмещающий пакет и пытаются отыскать импортируемые модули
в пути поиска sys.path.
Например, в обеих версиях Python, 3.0 и 2.6, инструкция вида:
from . import spam     # Импортирование относительно текущего пакета
предписывает интерпретатору импортировать модуль с именем spam, расположенный в том же пакете, что и файл, где находится эта инструкция. Аналогично, следующая инструкция:
from .spam import name
означает: «из модуля с именем spam, расположенного в том же пакете, что
и файл, где находится эта инструкция, импортировать переменную name».
Поведение инструкции безначальной точки зависит от используемой версии
Python. В версии 2.6 такая инструкция импортирования по умолчанию также
будет использовать порядок поиска «сначала относительно пакета, а затем – абсолютный поиск» (то есть сначала поиск выполняется в каталоге пакета), если
только в импортирующий файл не будет включена следующая инструкция:
from __future__ import absolute_import # Обязательно до версии2.7?
Если эта инструкция присутствует, она включает использование абсолютного
пути поиска, которое по умолчанию используется в Python 3.0.
В Python 3.0 все операции импортирования без дополнительных точек никогда
не пытаются отыскать модуль внутри пакета и производят поиск по абсолютно-му пути, хранящемуся в списке sys.path. Например, когда задействован меха-низм импортирования в версии 3.0, следующая инструкция всегда будет нахо-дить не модуль stringв текущем пакете, а одноименный модуль в стандартной библиотеке:
import string          # Пропустит поиск модуля в пакете
Без инструкции from __future__ в Python 2.6 всегда будет импортироваться модуль string из пакета. Чтобы получить то же поведение в версии 3.0 и 2.6, ког-да по умолчанию выполняется импорт по абсолютному пути, для выполнения
операции импортирования относительно пакета можно использовать следую-щую форму инструкции:
from . import string   # Поиск выполняется только в пределах пакета
На сегодняшний день этот прием работает в обеих версиях Python, 2.6 и 3.0.
Единственное отличие модели импортирования в версии 3.0 состоит в том, что
она является обязательной, когда требуется по простому имени загрузить модуль, находящийся в том же каталоге пакета, что и файл, откуда производится
импортирование.
Обратите внимание: ведущий символ точки может использоваться только в ин-струкции from – в инструкции importон недопустим. В Python 3.0 инструкция
import modnameвсегда выполняет импортирование по абсолютному пути, пропу-ская поиск в каталоге пакета. В Python 2.6 она по-прежнему выполняет импорт
по относительному пути (то есть сначала она просматривает каталог пакета),
но в Python 2.7 она будет выполнять импорт по абсолютному пути. Инструкции fromбез ведущей точки ведут себя точно так же, как инструкции import, – в версии 3.0 они выполняют импортирование по абсолютному пути (пропуская
каталог пакета), а в версии 2.6 они выполняют поиск «сначала относительно
пакета, а затем – абсолютный поиск» (поиск в каталоге пакета выполняется
в первую очередь).
Возможны также и другие варианты точечной нотации для ссылки на модули
в пакете. Допустим, что имеется каталог mypkg пакета, тогда следующие аль-
Импортирование относительно пакета
тернативные варианты импортирования внутри этого пакета будут работать
так, как описывается:
from .string import name1, name2 # Импорт имен из mypkg.string
from . import string             # Импорт mypkg.string
from .. import string            # Импорт string из родительского каталога
aCL
aCL
В run.py:
from module import a
input(a)

запуск run.py выводит вот это самое ‘qweqwe’

Учитывая написанное Лутцем, мой вопрос остается в силе и ответ на него интересует меня всё больше. Почему вышенаписанное имеет место быть? Из __init__.py даже убирал
from app import module
в тщетной попытке найти истину. Увы, не помогло.
Py 3.3.5
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB