标签: python flask web
引言:
用了半年多flask,趁现在项目比较稳定,好好研究一下
主要是一个提问题的思路:
1. 发现问题
2. 提出问题
3. 回答问题
希望能给各位看官讲明白。
本章问题:app = Flask(__ name__)
每位使用flask开发的朋友,都肯定看到过这么一个最简单的样例
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run()
程序很简单,差不多就是一个flask的最小程序。
但是,各位客观有没有思考过
app = Flask(__name__)
这一行是干嘛的呢?
那我首先想搞 __ name__是用来干嘛的
问题1: __ name__是什么
定义:
__name__是一个python内建的系统变量。
用途:
我们尝试使用
>>> print("__name__是个啥: {}".format(__name__))
__name__是个啥: __ main__
控制台告诉我们这个是__ main__
这就尴尬了 --||
那这个__ main__又是个啥?
通过查看python官方文档,我们得知:
__main__是顶层代码执行的作用域的名称。
简单来说,就是运行的入口模块的标识,它代表了入口模块名。
这么一看,__ name__就是入口模块名的表示变量了
ps:
1. 如果a = b,那么a = b为赋值语句,a为标识符,b为值。a称为b的表示变量, b为a的值
2. Python 模块(Module),是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句。
我们又发现我们的代码都写在一个模块里,那我们再做一个测试,把代码放在两个程序中运行:
# t1.py
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
print("t1的__name__: {}".format(__name__))
app.run()
# t2.py
from flask import Flask
app = Flask(__name__)
print("t2的__name__: {}".format(__name__))
# 输出
t2的__name__: test.t2
t1的__name__: __main__
诶,大家发现了没有,__ name__在t2中代表的是test.t2这个模块名,那我们可以进一步总结了
__name__代表了当前的模块名
结论1:Flask(name)接收模块名作为参数
问题2:接收这个模块名有啥用呢?
我们进到函数里看看
class Flask(_PackageBoundObject):
def __init__(
self,
import_name,
static_url_path=None,
static_folder='static',
static_host=None,
host_matching=False,
subdomain_matching=False,
template_folder='templates',
instance_path=None,
instance_relative_config=False,
root_path=None
):
_PackageBoundObject.__init__(
self,
import_name,
template_folder=template_folder,
root_path=root_path
)
...
name被复制给了import_name,然后我们通过全局搜索import_name发现,它是在这个函数下被使用
def get_root_path(import_name):
"""Returns the path to a package or cwd if that cannot be found. This
returns the path of a package or the folder that contains a module.
Not to be confused with the package path returned by :func:`find_package`.
"""
# Module already imported and has a file attribute. Use that first.
mod = sys.modules.get(import_name)
if mod is not None and hasattr(mod, '__file__'):
return os.path.dirname(os.path.abspath(mod.__file__))
# Next attempt: check the loader.
loader = pkgutil.get_loader(import_name)
# Loader does not exist or we're referring to an unloaded main module
# or a main module without path (interactive sessions), go with the
# current working directory.
if loader is None or import_name == '__main__':
return os.getcwd()
# For .egg, zipimporter does not have get_filename until Python 2.7.
# Some other loaders might exhibit the same behavior.
if hasattr(loader, 'get_filename'):
filepath = loader.get_filename(import_name)
else:
# Fall back to imports.
__import__(import_name)
mod = sys.modules[import_name]
filepath = getattr(mod, '__file__', None)
# If we don't have a filepath it might be because we are a
# namespace package. In this case we pick the root path from the
# first module that is contained in our package.
if filepath is None:
raise RuntimeError('No root path can be found for the provided '
'module "%s". This can happen because the '
'module came from an import hook that does '
'not provide file name information or because '
'it\'s a namespace package. In this case '
'the root path needs to be explicitly '
'provided.' % import_name)
# filepath is import_name.py for a module, or __init__.py for a package.
return os.path.dirname(os.path.abspath(filepath))
这个函数的注释也说的比较清晰,代码也相对简单,总结一下就是,通过这个import_name确定Flask这个核心对象被创建的根目录,以获得静态文件和模板文件的目录。
想想也是,我们在使用静态文件的时候也是没有添加过目录,原来是Flask框架在这里帮我们做了。