Flask Blueprint AttributeError: '模块'对象没有'名称'属性错误

33 投票
6 回答
43930 浏览
提问于 2025-04-29 11:40

我正在构建一个API,目的是让开发者可以扩展它的功能。我的计划是提供一个“extensions”目录,开发者可以把他们的蓝图放在里面,这样这些蓝图就会被动态加载。下面是我用来导入的代码(这个代码是从这个教程修改而来的)。

from flask import Flask

import pkgutil
import sys

app = Flask(__name__)

EXTENSIONS_DIR = "extensions"
modules = pkgutil.iter_modules(path=[EXTENSIONS_DIR])
for loader, mod_name, ispkg in modules: 
    if mod_name not in sys.modules:
        # It imports fine
        loaded_mod = __import__(EXTENSIONS_DIR+"."+mod_name+"."+mod_name, fromlist=[mod_name])
        # It does not register
        app.register_blueprint(loaded_mod)

这是我项目的目录结构。extensions目录就是开发者放置他们扩展功能的地方。

/root
    /extensions
        /extension1
            __init__.py
            extension1.py
        /extension2
            __init__.py
            extension2.py
    simple_example.py

问题是我遇到了一个错误,但我不太明白它在告诉我什么。

>python simple_example.py
Traceback (most recent call last):
  File "simple_example.py", line 14, in <module>
    app.register_blueprint(loaded_mod)
  File "C:\Python27\lib\site-packages\flask\app.py", line 62, in wrapper_func
    return f(self, *args, **kwargs)
  File "C:\Python27\lib\site-packages\flask\app.py", line 880, in register_blueprint
    if blueprint.name in self.blueprints:
AttributeError: 'module' object has no attribute 'name'

一个简单的扩展看起来是这样的:

from flask import Blueprint

extension1 = Blueprint('extension1', __name__)

@extension1.route("/my_route")
def treasure_list():
    return "list of objects"

我该如何解决这个AttributeError,才能让我的app.register_blueprint调用成功呢?

暂无标签

6 个回答

0

我之前是直接用 from flask import Flask 来导入蓝图的。后来我通过使用 pip3 install flask 重新安装了一下 Flask,解决了这个错误。有时候,如果你的 Flask 版本是 0.12.3 或更高,就可能会遇到这个问题。

2

我遇到了一个错误,提示说 AttributeError: 'Blueprint' object has no attribute 'register_blueprint'

为了解决这个问题,我简单地用 pip uninstall flask 卸载了 Flask,然后再安装了 flask[async],使用的命令是 pip install flask[async]

5

我在一个项目中也遇到过类似的问题。问题的根源是蓝图文件导入不正确。

确保你的导入语句是导入真正的蓝图,而不是定义蓝图的那个模块。

换句话说,你可能在做

from .blueprint import blueprint

而你其实想做的是

from .blueprint.blueprint import blueprint

另外一个小建议是,把定义蓝图的模块起个和蓝图不同的名字,这样可以让导入更加清晰。举个例子:

from .blueprint.views import blueprint
10

当我遇到这个错误时,我的代码是这样的:

from blueprints import api
...
app.register_blueprint(api)

我通过这样做解决了这个问题:

app.register_blueprint(api.blueprint)
41

你现在是在尝试注册一个模块,而不是里面的Blueprint对象。

你需要查看这个模块,去找到里面的Blueprint实例:

if mod_name not in sys.modules:
    loaded_mod = __import__(EXTENSIONS_DIR+"."+mod_name+"."+mod_name, fromlist=[mod_name])
    for obj in vars(loaded_mod).values():
        if isinstance(obj, Blueprint):
            app.register_blueprint(obj)

撰写回答