Flask AttributeError: объект модуля не имеет атрибута «приложение» - PullRequest
0 голосов
/ 16 апреля 2019

Я новичок во флаконе, и у меня был ниже атрибут AttributeError, связанный с импортом, когда flask run в папке flask_lab.

Любая помощь будет принята.

Рабочий каталог:

flask_lab
├── __init__.py
├── Pipfile
├── Pipfile.lock
├── README.md
├── tmp
│   ├── __init__.py
│   └── test.py
└── app.py

flask_lab / app.py:

import os
import click

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

import flask_lab.tmp.test.demo

app = Flask(__name__)
prefix = 'sqlite:////'
app.config['SQLALCHEMY_DATABASE_URI'] = prefix + os.path.join(app.root_path, 'data.db')
db = SQLAlchemy(app)

class User(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    name = db.Column(db.String(20))

flask_lab.tmp.test.demo()

flask_lab / tmp / test.py:

import flask_lab.app

print(flask_lab.app.db)


def demo():
    print('yeah!')

Ошибка:

Traceback (most recent call last):
  File "/home/huafeng/.local/share/virtualenvs/flask_lab-x_qc9OjH/bin/flask", line 10, in <module>
    sys.exit(main())
  File "/home/huafeng/.local/share/virtualenvs/flask_lab-x_qc9OjH/lib/python3.6/site-packages/flask/cli.py", line 894, in main
    cli.main(args=args, prog_name=name)
  File "/home/huafeng/.local/share/virtualenvs/flask_lab-x_qc9OjH/lib/python3.6/site-packages/flask/cli.py", line 557, in main
    return super(FlaskGroup, self).main(*args, **kwargs)
  File "/home/huafeng/.local/share/virtualenvs/flask_lab-x_qc9OjH/lib/python3.6/site-packages/click/core.py", line 717, in main
    rv = self.invoke(ctx)
  File "/home/huafeng/.local/share/virtualenvs/flask_lab-x_qc9OjH/lib/python3.6/site-packages/click/core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/huafeng/.local/share/virtualenvs/flask_lab-x_qc9OjH/lib/python3.6/site-packages/click/core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/huafeng/.local/share/virtualenvs/flask_lab-x_qc9OjH/lib/python3.6/site-packages/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "/home/huafeng/.local/share/virtualenvs/flask_lab-x_qc9OjH/lib/python3.6/site-packages/click/decorators.py", line 64, in new_func
    return ctx.invoke(f, obj, *args, **kwargs)
  File "/home/huafeng/.local/share/virtualenvs/flask_lab-x_qc9OjH/lib/python3.6/site-packages/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "/home/huafeng/.local/share/virtualenvs/flask_lab-x_qc9OjH/lib/python3.6/site-packages/flask/cli.py", line 767, in run_command
    app = DispatchingApp(info.load_app, use_eager_loading=eager_loading)
  File "/home/huafeng/.local/share/virtualenvs/flask_lab-x_qc9OjH/lib/python3.6/site-packages/flask/cli.py", line 293, in __init__
    self._load_unlocked()
  File "/home/huafeng/.local/share/virtualenvs/flask_lab-x_qc9OjH/lib/python3.6/site-packages/flask/cli.py", line 317, in _load_unlocked
    self._app = rv = self.loader()
  File "/home/huafeng/.local/share/virtualenvs/flask_lab-x_qc9OjH/lib/python3.6/site-packages/flask/cli.py", line 377, in load_app
    raise_if_not_found=False)
  File "/home/huafeng/.local/share/virtualenvs/flask_lab-x_qc9OjH/lib/python3.6/site-packages/flask/cli.py", line 235, in locate_app
    __import__(module_name)
  File "/home/huafeng/Desktop/flask_lab/app.py", line 7, in <module>
    import flask_lab.tmp.test.demo
  File "/home/huafeng/Desktop/flask_lab/tmp/test.py", line 3, in <module>
    print(flask_lab.app.db)
AttributeError: module 'flask_lab' has no attribute 'app'

Получены жалобы от stackoverflow о слишком большом количестве кода и недостаточно подробностей .... больше слов, больше слов ....

1 Ответ

0 голосов
/ 16 апреля 2019

При интерпретации app.py, если интерпретатор python встречает строку import flask_lab.tmp.test.demo, он немедленно начнет интерпретацию tmp / test.py.Но tmp / test.py снова импортирует flask_lab.

В этот момент, поскольку интерпретатор уже обнаружил flask_lab, он начнет поиск app в этом пространстве имен.Но оно никогда не доходило до этой черты.Поскольку вы уже импортировали tmp.test до того, как app было определено в модуле, flask_lab.app пока нет и, следовательно, ошибка.

И если бы вы напрямую вызвали tmp.test, вы бы также столкнулись с ошибкой циклического импорта.

Таким образом, выход состоит в том, чтобы избежать сценария циклического импорта.Переместите объект db в отдельный модуль и вызовите его в обоих этих модулях.Flask-SQLAlchemy предоставляет метод с именем init_app, предназначенный для такого случая использования.

Позволяет создать модуль с именем common, который будет содержать общие переменные.

flask_lab / common.py

from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()

flask_lab / app.py:

import os
import click

from flask import Flask
from .common import db
from .tmp.test import demo

class User(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    name = db.Column(db.String(20))

app = Flask(__name__)
prefix = 'sqlite:////'
app.config['SQLALCHEMY_DATABASE_URI'] = prefix + os.path.join(app.root_path, 'data.db')
db.init_app(app)

demo()

flask_lab / tmp / test.py:

from .common import db

print(db)


def demo():
    print('yeah!')

Обратите внимание, что я также заменил flask_lab импортс относительным импортом.Они чище.Код внутри пакета должен избегать использования имени пакета в импорте.Таким образом, если вы измените имя пакета позже, вы можете сделать это без изменения всего кода внутри.

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