Python flask应用程序在启动ImportError时引发以下错误:不支持按文件名导入

时间:2018-11-27 08:29:38

标签: python python-importlib

在安装了所有要求并通过

启动该应用程序后,我从git克隆了一个flask应用程序

$ 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)

在上面的错误中提到的第66行的 init .py中,

 # 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 :(得分:1)

几乎可以肯定,您的自动装带器正在做坏事(tm)

看起来您的代码旨在在Linux上运行,但是您正在Windows上运行它。就其本身而言,这并不一定是不好的,但并不是以支持这一点的方式编写的。具体来说,glob.glob(dir_path + "/*.py")返回目录中所有.py文件的路径,它们看起来像C:\\path\\to\\file.py。稍后,链module = file.replace(dir_path, "").replace("/", "").replace(".py", "")将尝试剥离.pyC:\\path\\to部分,使您剩下\\file,但是.replace('/', '')不会删除前导的反斜杠,因为它正在寻找正斜线,而Windows使用反斜线。然后,您将尝试导入\\file,这是您无法执行的操作,因为您无法将路径传递至__import__函数-这不是它的工作原理。

短期内,如果将ModuleImport工具更改为顶部的import os,您可能会发现一切都变得栩栩如生。然后将dir_path + "/*.py"替换为os.path.join(dir_path, '*.py'),并将replace("/", "")替换为replace(os.sep, "")。这应该可以解决您眼前的问题,但是您不应保留这样的代码。

从长远来看,这不是自动加载模块的好方法,并且如果您正在纠结importlib以使模块正确加载,则可能可以以更好的方式加载模块。当我看到诸如sys.path.appendimportlib.import之类的东西时,我通常认为这是一种代码气味。如果您查看How to load all modules in a folder?

,可能会发现代码更易于维护。

答案 1 :(得分:0)

硬编码路径不是一个好主意。

如果您使用的是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