一:Flask简介
Flask是一个Python编写的Web 微框架,让我们可以使用Python语言快速实现一个网站或Web服务,在介绍Flask之前首先来聊下它和Django的联系以及区别,django个大而全的web框架,它内置许多模块,flask是一个小而精的轻量级框架,Django功能大而全,Flask只包含基本的配置, Django的一站式解决的思路,能让开发者不用在开发之前就在选择应用的基础设施上花费大量时间。Django有模板,表单,路由,基本的数据库管理等等内建功能。与之相反,Flask只是一个内核,默认依赖于2个外部库: Jinja2 模板引擎和 WSGI工具集--Werkzeug , flask的使用特点是基本所有的工具使用都依赖于导入的形式去扩展,flask只保留了web开发的核心功能。
WSGI(web服务器网关接口)是python中用来规定web服务器如何与python Web服务器如何与Python Web程序进行沟通的标准,本质上就是一个socket服务端。而 Werkzeug模块 就是WSGI一个具体的实现
关键词:一个Python编写微web框架 一个核心两个库( Jinja2 模板引擎 和 WSGI工具集)
二:Flask的优点
flask性能上基本满足一般web开发的需求, 并且灵活性以及可扩展性上要优于其他web框架, 对各种数据库的契合度都非常高
关键词:1. 性能基本满足需求 2 .灵活性可拓展性强 3. 对各种数据库的契合度都比较高。
4.在真实的生产环境下,小项目开发快,大项目设计灵活
三:虚拟环境
1:优点
虚拟环境是隔离的Python解释器环境。通过创建虚拟环境,你可以拥有一个独立的Python解释器环境,相当于对全局的python解释器环境拷贝一份私有的副本, 这样做的好处是可以为每一个项目创建独立的Python解释器环境,因为不同的项目常常会依赖不同版本的库或Python版本。使用虚拟环境可以保持全局Python解释器环境的干净,避免包和版本的混乱,并且可以方便地区分和记录每个项目的依赖,所谓环境追根溯源也是文件,既然是文件就支持拷贝到各个平台上,所以同时提高了可移植性,以便在新环境下复现依赖环境。
举例说明:
例1:如果你同时有很多个项目,有一个爬虫项目,有一个Flask项目,有一个Django项目放在一个环境下,那么管理相关的第三方库难免混乱。
例2:如果你有两个Flask项目,但是两个项目flask版本不一致,会出现版本冲突问题
关键词:1、Python解释器的一个私有副本 2、解决了包管理混乱、版本冲突、提高了移植性
2:使用方式
(1)环境搭建
# windows的开发环境的安装过程,我们使用的是virtualenv虚拟开发环境,首先安装相关包的依赖 pip install virtualenvwrapper-win
(2)创建环境
mkvirtualenv + 虚拟环境名称
(3)常用命令
01、切换到指定的虚拟环境:注意我们进入虚拟环境是需要用workon命令,但是首次安装成功会自动进入虚拟环境。
workon + 虚拟环境名称
02、退出虚拟环境
deactivate
03、删除指定的虚拟环境
rmvirtaulenv + 虚拟环境名称
04、列出所有虚拟环境:
lsvirtualenv
05、进入到虚拟环境所在的目录:
cdvirtualenv
四:Flask使用方式
1:安装flask框架
# 安装flask框架 pip install flask
2:创建flask框架
2.1:第一步
2.2:第二步
3:文件夹解读
(1)static:存放 css js 图片等静态文件夹
(2)templates:存放html等html标签
(3)app.py:项目启动文件 app这个名字可以任意取
from flask import Flask app = Flask(__name__) @app.route('/') def hello_world(): return 'Hello World!' if __name__ == '__main__': app.run()
4:启动文件代码解读
4.1
from flask import Flask app = Flask(__name__) ''' 导入我们安装好的flask包,通过flask包导入Flask类,Flask类即为Flask的核心,实例化这个Flask类的到一个实例化对象app。 __name__这个特殊的参数:Python会根据所处的模块来赋予__name__变量相应的值,对于我们的程序来说(app.py),这个值为app。 '''
4.2
@app.route('/') def hello_world(): return 'Hello World!' ''' 这个 @app.route('/')就是用来匹配url的,在我们的flask里面是以装饰器来实现的,装饰器引用的也是我们上面实例化核心类出来的对象。 那么如果路由下面跟的函数什么呢 ?没错就是我们的视图函数,如果匹配到了路由就会触发我们的视图函数执行,并且return回具体的数据给前端或者移动端。 '''
4.3
if __name__ == '__main__': app.run() ''' app.run()源码如下去阅读源码不难发现,在内部定义了默认的 ip+端口为127.0.0.1:5000,并且调用了werkzeug.serving为我们创建了一个开发服务器(由依赖包Werkzeug提供),对套接字有一定了解的朋友,其内部就是做了一个循环监听的功能以便交互. 关键词:app.run()实现了flask程序在开发环境下运行起来,并且默认ip和端口是127.0.0.1:5000。 '''
4.3.1源码展示
def run(self, host=None, port=None, debug=None, load_dotenv=True, **options): ... _host ='127.0.0.1' _port = 5000 ... host = host or sn_host or _host port = int(port or sn_port or _port) ... from werkzeug.serving import run_simple try: run_simple(host, port, self, **options) finally: # reset the first request information if the development server # reset normally. This makes it possible to restart the server # without reloader and that stuff from an interactive shell. self._got_first_request = False
PS:
导入Flask的核心类实例化对象app,然后app作为装饰器使用匹配url分发给下面的视图函数,然后执行该页面会触发app调用run()方法运行起来整个项目
五:Werkzeug简介
1:简介
Werkzeug是一个WSGI工具包,他可以作为一个Web框架的底层库。这里稍微说一下, werkzeug 不是一个web服务器,也不是一个web框架,而是一个工具包,官方的介绍说是一个 WSGI 工具包,它可以作为一个 Web 框架的底层库,因为它封装好了很多 Web 框架的东西,例如 Request,Response 等等
2:代码示例
from werkzeug.wrappers import Request, Response @Request.application def hello(request): return Response('Hello World!') if __name__ == '__main__': from werkzeug.serving import run_simple run_simple('localhost', 4000, hello)
3:源码分析
3.1
看到了这个wekzeug是不是特别像我们的flask代码,没错我们的flask正是依赖于这个werkzeug模块,由wekzeug模块实现了socket服务端的功能,hello必然是加括号运行了,才会执行hello里面的代码,而在我们的flask中app.run()会调用run_simple(host, port, self, **options)
把上面代码例子的hello替换成了self也就是app。app()会触发Flask类的__call__
方法。
3.2
1 app.run() 调用 werkzeug.serving的run_simple(host, port, self, **options)
2 self()等价于app(), app()调用Flask类的__call__方法
3 Flask类的__call__方法返回了 self.wsgi_app(environ, start_response)
4 flask程序的执行过程都在 self.wsgi_app(environ, start_response)中
3.3
def run(self, host=None, port=None, debug=None, load_dotenv=True, **options): ... _host ='127.0.0.1' _port = 5000 ... host = host or sn_host or _host port = int(port or sn_port or _port) ... from werkzeug.serving import run_simple try: run_simple(host, port, self, **options) finally: # reset the first request information if the development server # reset normally. This makes it possible to restart the server # without reloader and that stuff from an interactive shell. self._got_first_request = False
def __call__(self, environ, start_response): """The WSGI server calls the Flask application object as the WSGI application. This calls :meth:`wsgi_app` which can be wrapped to applying middleware.""" return self.wsgi_app(environ, start_response) ... def wsgi_app(self, environ, start_response): ctx = self.request_context(environ) error = None try: try: ctx.push() response = self.full_dispatch_request() except Exception as e: error = e response = self.handle_exception(e) except: error = sys.exc_info()[1] raise return response(environ, start_response) finally: if self.should_ignore_error(error): error = None ctx.auto_pop(error)
六:Debug模式解析
1:作用
-
flask代码中如果出现了异常,我们在浏览器中不会提示具体的错误信息,开启debug模式后会把具体的错误信息发送到浏览器上。
-
flask代码如果被修改了,必须要重启项目修改的代码才会有效,开启debug模式后我们修改了代码只要
ctrl+s
我们的flask项目就会自动重新加载,不需要手动加载整个网站。
from flask import Flask app = Flask(__name__) @app.route('/') def hello(): a = [1,2,3,4] print(a[10]) # 代码越界 return "hello" if __name__ == '__main__': app.run()
2:代码修改
from flask import Flask app = Flask(__name__) app.debug = True # 开启debug模式 @app.route('/') def hello(): a = [1, 2, 3, 4] print(a[10]) # 代码越界 return "hello" if __name__ == '__main__': app.run()
2:Debug修改方式
1:方式一
from flask import Flask app = Flask(__name__) @app.route('/') def hello(): a = [1,2,3,4] print(a[4]) return "hello" if __name__ == '__main__': app.run(debug=True) # 设置
2:方式二
from flask import Flask app = Flask(__name__) app.debug = True # 设置 @app.route('/') def hello(): a = [1,2,3,4] print(a[4]) return "hello" if __name__ == '__main__': app.run()
3:方式三
from flask import Flask app = Flask(__name__) app.config.update(DEBUG=True) # 设置 @app.route('/') def hello(): a = [1,2,3,4] print(a[4]) return "hello" if __name__ == '__main__': app.run()
4:方式四
from flask import Flask import config # 导入config文件 app = Flask(__name__) app.config['DEBUG'] = True @app.route('/') def hello(): a = [1, 2, 3, 4] print(a[10]) # 代码越界 return "hello" if __name__ == '__main__': app.run()
5:方式五 创建一个config.py
,随着我们的学习会越来越多的用到这个配置文件,来配置我们的flask
项目,注意配置的信息一般为大写。
from flask import Flask import config # 导入config文件 app = Flask(__name__) app.config.from_object(config) @app.route('/') def hello(): a = [1, 2, 3, 4] print(a[10]) # 代码越界 return "hello" if __name__ == '__main__': app.run()