Приложение Python flask выдает следующую ошибку при запуске ImportError: Импорт по имени файла не поддерживается - PullRequest
0 голосов
/ 27 ноября 2018

У меня есть приложение-фляга, клонированное из git, после установки всех его требований и запуска приложения с помощью

$ python start.py

Я получаю следующую ошибку

Traceback (most recent call last):
  File "start.py", line 6, in <module>
    app = create_app("local")
  File "C:\Jahangeer\qurbcode\api\app\__init__.py", line 66, in create_app
    from app.api_1_0 import apibp as api_1_0, api_spec as api_1_0_spec
  File "C:\Jahangeer\qurbcode\api\app\api_1_0\__init__.py", line 78, in <module>
    ModuleImport.importModulesFromPath(os.path.dirname(os.path.realpath(__file__)), __name__)
  File "C:\Jahangeer\qurbcode\api\app\helpers\module_import.py", line 16, in importModulesFromPath
    importlib.import_module("." + module, package)
  File "C:\Python27\lib\importlib\__init__.py", line 37, in import_module
    __import__(name)
ImportError: Import by filename is not supported.

Start.py имеет следующий код

import os
from app import create_app

app = create_app("local")

if __name__ == '__main__':
    app.run(host= '0.0.0.0', threaded=True)

, а внутри моего init .py в строке 66, о котором упоминается в приведенной выше ошибке, следующий

 # Setup api/1.0 blueprint
    from .api_1_0 import apibp as api_1_0, api_spec as api_1_0_spec
    from .admin import admin_bp as admin
    app.register_blueprint(api_1_0, url_prefix='/api/1.0')

Вот структура приложения

api
->admin_app
->app
  ->admin
  ->api_1_0
  ->__init__.py
->start.py
->manage.py

Мой api \ app \ helpers \ module_import.py имеет следующий код:

import glob
import importlib


class ModuleImport:

    @staticmethod
    def importModulesFromPath(dir_path, package, import_init = False):
        files = glob.glob(dir_path + "/*.py")
        for file in files:
            module = file.replace(dir_path, "").replace("/", "").replace(".py", "")

            if module == "__init__" and not import_init:
                continue

            importlib.import_module("." + module, package)

и мой api \ app \ api_1_0__init __. Py имеютследующий код: в строке 78

ModuleImport.importModulesFromPath(os.path.dirname(os.path.realpath(__file__)), __name__)

Ответы [ 2 ]

0 голосов
/ 27 ноября 2018

Это не очень хорошая идея для жестких путей кода.

Вы можете использовать pathlib, если используете Python 3, или os.path.join в противном случае.

from pathlib import Path

data_folder = Path("source_data/text_files/")

file_to_open = data_folder / "raw_data.txt"

f = open(file_to_open)

print(f.read())

или даже если вы хотите получить путь к Windows:

from pathlib import Path, PureWindowsPath

filename = PureWindowsPath("source_data\\text_files\\raw_data.txt")

correct_path = Path(filename)

print(correct_path)
# "source_data/text_files/raw_data.txt" on Mac and Linux
# "source_data\text_files\raw_data.txt" on Windows
0 голосов
/ 27 ноября 2018

Ваш автозагрузчик почти наверняка совершает ошибку (tm) .

Похоже, ваш код предназначен для работы в Linux, но вы запускаете его в Windows.Само по себе это не обязательно плохо, но написано не так, чтобы это поддерживалось.В частности, glob.glob(dir_path + "/*.py") возвращает вам пути ко всем .py файлам в каталоге, и они будут выглядеть как C:\\path\\to\\file.py.Позже цепочка module = file.replace(dir_path, "").replace("/", "").replace(".py", "") попытается очистить части .py и C:\\path\\to, оставив вам \\file, но .replace('/', '') не удалит этот ведущий обратный слеш, потому что он ищет косые черты и использует окнаобратные косые.Затем вы попытаетесь импортировать \\file, чего вы не можете сделать, потому что вы не можете передать путь к функции __import__ - это не так.

В краткосрочной перспективе выможет случиться так, что все оживет, если вы поменяете свой инструмент ModuleImport на import os вверху.Затем замените dir_path + "/*.py" на os.path.join(dir_path, '*.py') и replace("/", "") на replace(os.sep, "").Это должно решить вашу непосредственную проблему, но вы не должны оставлять код таким.

В долгосрочной перспективе, это не хороший способ для автозагрузки модулей, и если вы облажаетесь с importlib, чтобы получить ваши модулидля правильной загрузки вы, вероятно, сможете загружать свои модули гораздо лучше.Я обычно считаю это запахом кода, когда вижу такие вещи, как sys.path.append или importlib.import, бегающие вокруг.Может показаться, что ваш код легче поддерживать, если вы посмотрите на Как загрузить все модули в папке?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...