当前位置: 首页 > 后端技术 > Python

【翻译】为什么我们要将__name__传递给Flask类?

时间:2023-03-26 18:38:31 Python

翻译为什么我们要将__name__传递给Flask类?当您学习Flask时,系统会告诉您通过将__name__作为第一个参数传递给Flask类来创建Flask应用程序实例。大多数开发者这样做的时候没有考虑过,不知道能达到什么效果。在本文中,我们将深入探讨Flask(__name__)。最后,您不仅会完全理解模式,还会知道何时丢弃它并传递其他值。什么名字__?Python将__name__变量设置为模块名称,因此该变量的值将根据使用它的Python源文件而有所不同。例如,在应用程序顶级目录中名为test.py的模块中,__name__的值为test。如果test.py模块位于名为my_package的Python包中,则__name__的值为my_package.test。__name__的值有两个特殊的例外:在__init__.py包构建模块中,__name__的值是包名而不是__init__.py。比如在my_package/__init__.py中,__name__的值为my_package。在应用程序的主模块(运行Python解释器的文件)中,__name__具有特殊值__main__的值。Flask文档中的__name__如果您阅读Flask文档,就会发现Flask类的第一个参数称为import_name。它被描述为“应用程序包的名称”。文档建议您“正常”通过为该参数传递__name__来创建Flask实例,而无需详细说明原因。在标题为“关于第一个参数”的小节中,有更多关于import_name参数用途的信息,列出了它的三种不同用途:在文件系统上查找资源由扩展使用以改进调试信息更多(???)令人困惑,对吧?让我们一一看看。找资源这个其实乍一看比较容易理解。此上下文中的术语“资源”是指应用程序所需的附加文件,例如静态文件和模板文件。你有没有想过Flask是如何知道去哪里寻找这些文件的?它的工作原理如下。Flask接受作为导入包名称传递的参数,并尝试通过查找具有该名称的模块对象来使用它来确定应用程序的根路径。一旦它知道这个路径,它就会连接静态和模板目录名称,这就是它获取这些文件的地方。在flask/helpers.py模块中有一个名为get_root_path()的函数,Flask使用它来获取应用程序的根目录。这个函数完成了导航Python导入系统的所有脏活,以找到名称为import_name参数的模块。让我们快速浏览一下get_root_path()函数。对于下面的测试,我将使用FlaskMega-Tutorial中的微博应用程序。正确安装应用程序后,我启动Python会话并使用几个不同的值调用get_root_path()函数以查看结果:>>>fromflask.helpersimportget_root_path#theapppackage>>>get_root_path('app')'/home/miguel/microblog/app'#flask包>>>get_root_path('flask')'/home/miguel/microblog/venv/lib/python3.8/site-packages/flask'#thethreadingpackage>>>get_root_path('threading')'/home/miguel/.pyenv/versions/3.8.6/lib/python3.8'#config.py模块>>>get_root_path('config')'/Users/mgrinberg/Documents/dev/python/microblog'#app/models.py模块>>>get_root_path('app.models')'/Users/mgrinberg/Documents/dev/python/microblog/app'#app.api包>>>get_root_path('app.api')'/Users/mgrinberg/Documents/dev/python/microblog/app/api'#app.api.auth.py模块>>>get_root_path('app.api.auth')'/Users/mgrinberg/Documents/dev/python/microblog/app/api'从这些例子中,我们可以推断出Flask用来确定根路径的规则:如果以包名作为参数调用Flask(),然后应用程序的根路径就是包如果调用Flask()并将模块名称作为参数传递,那么应用程序的根路径就是模块所在包的目录。import_name参数还有第二种用法。Flask有一个不起眼的功能,称为实例文件夹,它是存储不受源代码控制的配置文件的特殊文件夹。确定应用实例文件夹位置的方法是一样的,使用import_name找到根路径,然后在其中添加一个实例子目录。我应该注意,默认的根路径和实例路径都可以在Flask构造函数中使用root_path和instance_path参数覆盖。改进Flask扩展中的调试信息这个问题很难搞清楚。我发现唯一使用import_name参数的Flask扩展是Flask-SQLAlchemy。该扩展有一个get_debug_queries()函数,用于收集和记录在请求生命周期内发出的所有查询。记录的属性之一是在应用程序源代码中发出查询的位置。获取此信息实际上非常困难,Flask-SQLAlchemy在查询完成时沿着调用堆栈向上移动,直到找到与应用程序的import_name匹配的源位置。虽然这是一项非常酷的技术,但它也非常神奇和晦涩。我还没有看到它在任何其他Flask扩展中使用过。更多我查看了Flask源代码以了解import_name参数的其他用途,发现另外两个案例值得一提。一个是Blueprint类,将蓝图名称作为第一个参数,import_name作为第二个参数。蓝图中参数的使用与查找特定于蓝图的资源有关,这些资源的工作方式与在应用程序实例中的工作方式相同。使用import_name参数的另一个有趣的地方是命名应用程序实例。打印应用实例时显示应用的名字:>>>fromflaskimportFlask>>>app=Flask('foo')>>>app这个名字赋值给Click命令线接口主组。如果项目的FlaskCLI作为一个组附加到父CLI,则此名称将是用于访问Flask应用程序命令的组名。