# 上下文:html
### Local对象:
在`Flask`中,相似于`request`的对象,实际上是绑定到了一个`werkzeug.local.Local`对象上。这样,即便是同一个对象,那么在多个线程中都是隔离的。相似的对象还有`session`以及`g`对象。python
### Thread Local对象:
只要知足绑定到这个对象上的属性,在每一个线程中都是隔离的,那么他就叫作`Thread Local`对象。flask
### 应用上下文和请求上下文:
应用上下文和请求上下文都是存放到一个`LocalStack`的栈中。和应用app相关的操做就必需要用到应用上下文,好比经过`current_app`获取当前的这个`app`。和请求相关的操做就必须用到请求上下文,好比使用`url_for`反转视图函数。
1. 在视图函数中,不用担忧上下文的问题。由于视图函数要执行,那么确定是经过访问url的方式执行的,那么这种状况下,Flask底层就已经自动的帮咱们把请求上下文和应用上下文都推入到了相应的栈中。
2. 若是想要在视图函数外面执行相关的操做,好比获取当前的app(current_app),或者是反转url,那么就必需要手动推入相关的上下文:session
1 * 手动推入app上下文: 2 ```python 3 # 第一种方式: 4 app_context = app.app_context() 5 app_context.push() 6 # 第二种方式: 7 with app.app_context(): 8 print(current_app) 9 ``` 10 * 手动推入请求上下文:推入请求上下文到栈中,会首先判断有没有应用上下文,若是没有那么就会先推入应用上下文到栈中,而后再推入请求上下文到栈中: 11 ```python 12 with app.test_request_context(): 13 print(url_for('my_list')) 14 ```
### 为何上下文须要放在栈中:
1. 应用上下文:Flask底层是基于werkzeug,werkzeug是能够包含多个app的,因此这时候用一个栈来保存。若是你在使用app1,那么app1应该是要在栈的顶部,若是用完了app1,那么app1应该从栈中删除。方便其余代码使用下面的app。
2. 若是在写测试代码,或者离线脚本的时候,咱们有时候可能须要建立多个请求上下文,这时候就须要存放到一个栈中了。使用哪一个请求上下文的时候,就把对应的请求上下文放到栈的顶部,用完了就要把这个请求上下文从栈中移除掉。app
### 保存全局对象的g对象:
g对象是在整个Flask应用运行期间都是可使用的。而且他也是跟request同样,是线程隔离的。这个对象是专门用来存储开发者本身定义的一些数据,方便在整个Flask程序中均可以使用。通常使用就是,将一些常常会用到的数据绑定到上面,之后就直接从g上面取就能够了,而不须要经过传参的形式,这样更加方便。函数
### 经常使用的钩子函数:
在Flask中钩子函数是使用特定的装饰器装饰的函数。为何叫作钩子函数呢,是由于钩子函数能够在正常执行的代码中,插入一段本身想要执行的代码。那么这种函数就叫作钩子函数。(hook)
1. `before_first_request`:Flask项目第一次部署后会执行的钩子函数。
2. `before_request`:请求已经到达了Flask,可是尚未进入到具体的视图函数以前调用。通常这个就是在视图函数以前,咱们能够把一些后面须要用到的数据先处理好,方便视图函数使用。
3. `context_processor`:使用这个钩子函数,必须返回一个字典。这个字典中的值在全部模版中均可以使用。这个钩子函数的函数是,若是一些在不少模版中都要用到的变量,那么就可使用这个钩子函数来返回,而不用在每一个视图函数中的`render_template`中去写,这样可让代码更加简洁和好维护。
4. `errorhandler`:在发生一些异常的时候,好比404错误,好比500错误。那么若是想要优雅的处理这些错误,就可使用`errorhandler`来出来。须要注意几点:
* 在errorhandler装饰的钩子函数下,记得要返回相应的状态码。
* 在errorhandler装饰的钩子函数中,必需要写一个参数,来接收错误的信息,若是没有参数,就会直接报错。
* 使用`flask.abort`能够手动的抛出相应的错误,好比开发者在发现参数不正确的时候能够本身手动的抛出一个400错误。
示例代码以下:测试
1 ```python 2 @app.errorhandler(404) 3 def page_not_found(error): 4 return render_template('404.html'),404 5 ```