Как импортировать чертежи с тем же именем, что и файл, в котором они находятся?

#python #flask #python-import

#python #flask #python-импорт

Вопрос:

Предыстория

Я пытаюсь настроить схему элементов, имя которой соответствует имени файла, в котором она находится, чтобы, когда я ссылаюсь на нее в моем app.py , я знал, откуда взят проект. Это должно быть возможно, потому что в примере на exploreflask используется тот же шаблон. Тем не менее, я не могу понять, как заставить это работать с моей структурой.

Структура файла

 ├── app.py
├── frontend
    ├── __init__.py
    └── views
        ├── home.py
        └── __init__.py
  

Пример

frontend/views/home.py

 from flask import Blueprint, render_template

home = Blueprint('home', __name__)
home1 = Blueprint('home1', __name__)
  

frontend/views/__init__.py

 from .home import home
from .home import home1
  

app.py

 from flask import Flask

from frontend.views import home
from frontend.views import home1

print (type(home))  --> <class 'function'> 
print (type(home1)) --> <class 'flask.blueprints.Blueprint'>
  

As home1 правильно регистрируется как a, Blueprint но home я не подозреваю, что
существует конфликт имен, но я не знаю, как его разрешить, несмотря на изучение
эта превосходная статья об импорте соглашений.

В результате, когда я пытаюсь зарегистрировать свои чертежи в приложении, это сработает:

 app.register_blueprint(home1, url_prefix='/home1') --> Fine
  

но это не приведет:

 app.register_blueprint(home, url_prefix='/home')
--> AttributeError: 'function' object has no attribute 'name'
  

Почему бы просто не согласиться с использованием home1?

  1. Я хочу понять, как можно разрешить коллизию
  2. Я хочу иметь возможность использовать имена маршрутов, совпадающие с именем файла, в котором они находятся, вот так:

frontend/views/home.py

 from flask import Blueprint, render_template

home = Blueprint('home', __name__)

@home.route('/')
def home():
  pass
  

Комментарии:

1. Вы пытаетесь использовать разделенную или функциональную структуру, описанную в exporeflask ?

Ответ №1:

Я думаю, что ваш views/__init__.py файл вызывает эту проблему. Это заставляет python предполагать, что ваш home.py файл является импортируемым модулем. Я полагаю, что строка from frontend.views import home пытается импортировать home.py файл, а не ваш предполагаемый home.home чертеж.

Вот рабочий пример:

/app.py

 from app import create_app
app = create_app()

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

/app/__init__.py

 from flask import Flask

def create_app():
    app = Flask(__name__) 
    from .bp import bp  
    app.register_blueprint(bp)   
    return app
  

/app/bp/__init__.py

 from flask import Blueprint
bp = Blueprint('bp', __name__, template_folder='templates')
from . import views
  

/app/bp/views.py

 from app.bp import bp

@bp.route('/helloworld')
def helloworld():

    return "hello world"
  

Ответ №2:

Попробуйте использовать заглавные буквы в модуле Blueprint.

также вы можете использовать url_prefix в модуле.

 Home = Blueprint("Home", __name__, url_prefix="/home")

@Home.route("/")
def home():
    pass
  

Комментарии:

1. Использование заглавных букв может быть сложным решением, но это именно то, чего я хотел бы избежать. Кроме того, это нарушает PEP8: заглавные буквы обозначают классы. url_prefix Не имеет отношения к проблеме (и я все равно ее уже использую).