Python не может импортировать модуль из пакета - PullRequest
0 голосов
/ 09 марта 2019

У меня есть проект колбы для отдыха со следующей компоновкой (имена файлов изменены для удобства)

myproject/
    __init__.py
    app.py
    common/
        __init__.py
        util.py
    foo/
        __init__.py
        main.py
        utilities.py

foo/ - это просто папка, содержащая код для одной из конечных точек API, я планируюдобавьте другие в будущем, по этой причине у меня есть файл common/util.py, который содержит многократно используемые функции, которые я буду использовать с другими конечными точками API.

foo/main.py

from flask_restful import Resource, request

from utilities import Analysis

class Foo(Resource):
    def get(self):      
        pass

в foo/utilities.py У меня есть классы с методами, которые получают некоторые данные, я импортирую эти классы в foo/main.py, чтобы вернуть ответ JSON

Классы в foo/utilities.py также используют некоторые функции из common/util.py, но когда япопробуйте импортировать что-то из common/util.py в foo/utilities.py Я получаю import common.util ModuleNotFoundError: No module named 'common'

Что может быть причиной этого?Я пытался импортировать различными способами: from common.util import my_func from .common.util import my_func from myproject.common.util import my_func

, но ни один не работал.

Это myproject/app.py в случае, если это имеет значение:

from flask import Flask
from flask_restful import Api

from foo.main import Foo

app = Flask(__name__)
api = Api(app)

api.add_resource(Foo, '/Foo')

if __name__ == "__main__":
    app.run()

Я делаю все это в активированном virtualenv, если это имеет значение

1 Ответ

1 голос
/ 09 марта 2019

из common.util import my_func

В Python 3 это абсолютный импорт, то есть каталог с подкаталогом common/ должен находиться в sys.path. В вашей ситуации это, безусловно, неправильный подход.

из .common.util import my_func

Этот импорт предполагает, что common будет подкаталогом foo, что также не соответствует действительности.

из myproject.common.util import my_func

Это, наконец, лучший подход, но для его работы родительский каталог подкаталога myproject/ должен находиться в sys.path. Либо вы устанавливаете весь myproject, либо добавляете родительский каталог в переменную среды $PYTHONPATH, либо добавляете каталог в sys.path в foo/main.py. Что-то вроде:

PYTHONPATH=/home/to/parentdir /home/to/parentdir/myproject/foo/main.py

или

import sys
sys.path.insert(0, '/home/to/parentdir')

/home/to/parentdir - это каталог, где myproject/.

После установки myproject или добавления его родительского каталога в sys.path вы также можете использовать относительный импорт. Вы должны помнить, что common является родственным пакетом по сравнению с foo, поэтому импорт должен быть не из .common, а из ..common:

from ..common.util import my_func
...