Flask:Locla;偏函数;请求上下文;蓝图;g对象;信号;flask-session

一 Local:

一.为什么需要local

1.作用:为每个线程或协程创建一个独立的空间,使得线程或协程对自己的空间中的数据进行操作(数据隔离和数据安全)。

二.使用

1.兼容线程和协程(源码到request中去看,看local的getattr,setattr)

try:
    from greenlet import getcurrent as get_ident
except Exception as e:
    from threading import get_ident
# 导入线程
from threading import Thread
import time

# local类
class Local(object):
    def __init__(self):
        object.__setattr__(self,'storage',{})
    def __setattr__(self, k, v):
        ident = get_ident()
        if ident in self.storage:
            self.storage[ident][k] = v
        else:
            self.storage[ident] = {k: v}
    def __getattr__(self, k):
        ident = get_ident()
        return self.storage[ident][k]
obj = Local()

# 任务函数
def task(arg):
    obj.val = arg
    time.sleep(2)
    print(obj.val)

# 开启线程
for i in range(10):
    t = Thread(target=task,args=(i,))
    t.start()
兼容线程和协程

2.其他使用方式:

day91:https://www.cnblogs.com/lovershowtime/p/11747169.html

二.偏函数

链接:https://blog.csdn.net/JSYhq/article/details/88633426

一.什么是偏函数

作用:主要是将一个或多个参数预先赋值,以便函数能用更少的参数进行调用。

二.使用

  • 1.导入模块:from functools import partial
  • 2.mysum = partial(函数名, 预传参数1,预传参数2,...)
  • 3.调用:mysum(剩余参数1,剩余参数2,..)
  • 第一个参数:自定义函数或者是python内置函数
  • 第二个参数:可变参数,如果没有指定关键字,按原有函数的参数顺序进行补充,参数将作 用在原函数上,如果指定关键字就对应到所指位置

1.常用示例:

from functools import partial
def
add(a, b): return a + b if __name__ == "__main__": # 重新生成一个偏函数对象(其中一个参数已知),并赋予mysum,然后再调用这个新函 # 数对象,10为预先设定的参数 mysum = partial(add, 10) print mysum(5) # 15

2.关键字示例:

from functools import partial
def
add(a, b=2): return a + b def add2(a=2, b=3): return a + b if __name__ == "__main__": mysum = partial(add, 10) print mysum() # 也可根据关键字预先设定的参数值 mysum2 = partial(add, b=3) print mysum2(1) # 如果没有关键字,按原有参数顺序补充 mysum3 = partial(add2, 1) print mysum3() # 结果 12 4 4

三. 请求上下文源码分析

链接:https://www.cnblogs.com/caochao-/articles/8963610.html

四 .蓝图

一.蓝图简介

1.什么是蓝图:

如果我们将所有的Flask的请求方法都写在同一个文件下的话,非常的不便于我们的代码的管理和后期的功能代码的添加,简单来说蓝图就是实现一个模块化和结构目录划分

二 .具体使用

1.分大小型项目具体详见文件夹代码示范

2.注意点和基本语法

# 1.导入蓝图模块
from flask import Blueprint

# 2.创建蓝图对象
蓝图对象名 = Blueprint(
    '任意名(一般为应用名)',
    任意名(一般为__name__),
    template_folder='模板文件',
    static_folder='静态文件',
url_prefix='路由前缀'
)
# 示例
web = Blueprint(
    'web',
    __name__,
    template_folder='templates',
    static_folder='static',
url_prefix='/web'
)

# 3.蓝图对象注册
from flask import Flask
# 导入蓝图对象
from .web import web
app = Flask(__name__)
app.register_blueprint(蓝图对象)

# 4.视图函数使用
web.route('/index')
def index():
    return 'Web.Index'
注意:1.路由前缀可以在创建蓝图对象或者注册时都可设置选其一
2.公共的请求方式在文件项目下的init文件中写如:
@app.before_request装饰方法

五.G对象

一. G对象简介

1.什么是G对象:专门用来存储用户信息的g对象,g的全称的为global

2.G对象的特性:

当前请求生命周期内内设置就可以取无限次,其他请求生命周期内没设置值就无法取值
就算你当前请求,设置了,如果不取,其他请求过来,也取不到

3.g对象和session的区别

session对象是可以跨request的,只要session还未失效,不同的request的请求会获取到同一个session,但是g对象不是,g对象不需要管过期时间,请求一次就g对象就改变了一次,或者重新赋值了一次

二.用法

# 1.导入g对象
from  flask import Flask,request,g,redirect

# 2.设置值
g.k= v

# 3.取值
g.k

# 示例代码
from  flask import Flask,request,g,redirect

app=Flask(__name__)
def set_g():
    g.name='sb'

@app.route("/")
def index():
    set_g() # g对象设置值
     print(g.name) # 取得到
    return redirect("/index") # 重定向,此路由生命周期结束,另一条生命周期开启


@app.route("/index")
def login():
    print(g.name) # 报错 取不到,此生命周期没设置值
    return "2"

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

六.信号

一.信号简介

1.什么是信号:

Flask框架中的信号基于blinker,其主要就是让开发者可是在flask请求过程中定制一些用户行为

2.内置信号

request_started = _signals.signal('request-started')                # 请求到来前执行
request_finished = _signals.signal('request-finished')              # 请求结束后执行
 
before_render_template = _signals.signal('before-render-template')  # 模板渲染前执行
template_rendered = _signals.signal('template-rendered')            # 模板渲染后执行
 
got_request_exception = _signals.signal('got-request-exception')    # 请求执行出现异常时执行
 
request_tearing_down = _signals.signal('request-tearing-down')      # 请求执行完毕后自动执行(无论成功与否)
appcontext_tearing_down = _signals.signal('appcontext-tearing-down')# 应用上下文执行完毕后自动执行(无论成功与否)
 
appcontext_pushed = _signals.signal('appcontext-pushed')            # 应用上下文push时执行
appcontext_popped = _signals.signal('appcontext-popped')            # 应用上下文pop时执行
message_flashed = _signals.signal('message-flashed')                # 调用flask在其中添加数据时,自动触发

二.内置信号使用和自定义信号

使用前提:

pip3 install blinker

1.内置使用:

注意:

无需管调用,因为flask,已经给我们设置调用点
#1.导入模块
from flask import Flask,signals,render_template

app = Flask(__name__)

# 2.信号函数
def func(*args,**kwargs):
    print('触发型号',args,kwargs)
# 3.绑定信号函数
signals.request_started.connect(func)

# 触发信号: signals.request_started.send()
@app.before_first_request
def before_first1(*args,**kwargs):
    pass
@app.before_first_request
def before_first2(*args,**kwargs):
    pass

@app.before_request
def before_first3(*args,**kwargs):
    pass

@app.route('/',methods=['GET',"POST"])
def index():
    print('视图')
    return '123'


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

2.自定义(需要自己进行调用,调用时第一个为位置参数其他为关键字)

from flask import Flask, current_app, flash, render_template
# 1.导入模块
from flask.signals import _signals

app = Flask(import_name=__name__)

# 2.自定义信号
xxxxx = _signals.signal('xxxxx')

# 3.信号函数 
def func(sender, *args, **kwargs):
    print(sender)

# 4.自定义信号中注册函数
xxxxx.connect(func)

@app.route("/x")
def index():
    
# 5.触发信号
    xxxxx.send('123123', k1='v1')
    return 'Index' 
 
if __name__ == '__main__':
    app.run()

七.flask-session

一.flask-session简介

1.作用:

将session值 保存到 redis/memcached/file/Mongodb/SQLAlchemy

2.安装

安装:pip3 install flask-session

二.两种使用方式

from flask import Flask,session
from flask_session import RedisSessionInterface
from redis import Redis
app=Flask(__name__)

# app.secret_key='sdfasdfee'

#方式一
conn=Redis()
# key_prefix值可任意设置,use_signer=False默认的不需要设置app.secret_key,permanent=False关闭浏览器session失效
pp.session_interface=RedisSessionInterface(conn,key_prefix='jason',use_signer=False, permanent=False)

#方式二:用的比较多
# from redis import Redis
# from flask_session import Session
# app.config['SESSION_TYPE'] = 'redis'
# app.config['SESSION_REDIS'] = Redis(host='192.168.0.94',port='6379')
# Session(app)

@app.route('/')
def index():
    session['name']='lqz'

    return "hello world"
if __name__ == '__main__':
    app.run()
原文地址:https://www.cnblogs.com/tfzz/p/11852457.html