flask的local的使用,以及local的原理推导

flask的local的使用以及原理的推导

import time

from threading import Thread, local, get_ident # 获取线程的id

# 这是使用local对象的写法,下面我们会分析推导local对象的原理
a = local()

def task(arg):
    a.value = arg
    time.sleep(1)
    print(a.value)

for i in range(10):
    t = Thread(target=task, args=(i,))
    t.start()

#推导1 用函数的形式来模拟local
storage = {}
def set(k,v):
    # 获取线程id
    ident = get_ident()
    if ident in storage:
        # 如果线程id在里面,重新赋值
        storage[ident][k] = v
    else:
        # 不在里面就以线程id为key,k,v为字典存进去
        storage[ident] = {k:v}

def get(k):
    ident = get_ident()
    return storage[ident][k]

def task(arg):
    set('k', arg)
    time.sleep(1)
    v = get('k')
    print(v)

for i in range(10):
    t = Thread(target=task, args=(i,))
    t.start()

# 推导2 面向对象版
class Local:
    storage = {}

    def set(self, k, v):
        ident = get_ident()
        if ident in Local.storage:
            Local.storage[ident][k] = v
        else:
            Local.storage[ident] = {k:v}

    def get(self,k):
        ident = get_ident()
        return Local.storage[ident][k]

obj = Local()

def task(arg):
    obj.set('k', arg)
    time.sleep(1)
    v = obj.get('k')
    print(v)

for i in range(10):
    t = Thread(target=task, args=(i,))
    t.start()

# 推导3 面向对象的setattr,getattr版
class Local:
    storage={}

    def __setattr__(self, k, v):
        ident = get_ident()
        if ident in Local.storage:
            Local.storage[ident][k] = v
        else:
            Local.storage[ident] = {k:v}

    def __getattr__(self, k):
        ident = get_ident()
        return Local.storage[ident][k]

obj = Local()

def task(arg):
    obj.val = arg  # 对象.属性=属性值走__setattr__方法
    time.sleep(1)
    print(obj.val) # 对象.属性当没有改属性时,走__getattr__方法

for i in range(10):
    t = Thread(target=task, args=(i,))
    t.start()

# 推导4 面向对象,将storage变成对象的属性
class Local(object):

    def __init__(self):
        # 防止getattr出现递归,我们在父类中设置storage属性
        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  # 对象.属性=属性值走__setattr__方法
    time.sleep(1)
    print(obj.val) # 对象.属性当没有改属性时,走__getattr__方法

for i in range(10):
    t = Thread(target=task, args=(i,))
    t.start()

原文地址:https://www.cnblogs.com/yafeng666/p/12534039.html

时间: 2024-08-30 17:17:58

flask的local的使用,以及local的原理推导的相关文章

Flask解析(一):Local、LocalStak、LocalProxy

Local是什么? 无论你接触到的是threading.Local还是werkzeug.Local,它们都代表一种变量——每个线程自己的全局变量. 全局变量,一般位于进程的堆上.一个进程的所有线程都可以访问同一个全局变量,因为它们共享着进程的地址空间,所以每一个线程都可以访问,这也带来了问题,如果多个线程同时访问同一个变量,会对该变量的读写造成不可预估的结果,所以通常我们会使用锁或其他的同步机制来控制线程之间对共享变量的访问.当然了,这不是本文关注的地方. 说回Local,我们在开头提到Loca

Flask request,g,session的实现原理

最近一直在研究Flask,由于gfirefly中提供的Http接口使用了Flask,以前都是写一些游戏中简单的操作,最近涉及到Flask的方面比较多,所以就认真研究了下.对Flask的request context和app context略有心得,所以和小伙伴们分享一下Flask的request原理. 在我们视图中要使用request时只需要from flask import request就可以了很好奇在多线程的环境下,是如何保证request没有混乱的在flask.globals.py中 d

内置系统账户:Local system/Network service/Local Service 区别

LocalSystem   账户 LocalSystem是预设的拥有本机所有权限的本地账户,这个账户跟通常的用户账户没有任何关联,也没有用户名和密码之类的凭证.这个服务账户可以 打开注册表的HKEY_LOCAL_MACHINE/Security键,当LocalSystem访问网络资源时,它是作为计算机的域账户使用的. 举例来说,以LocalSystem账户运行的服务主要有:WindowsUpdate   Client.   Clipbook.Com+.DHCP   Client.Messenge

Local prefixed index和Local nonprefixed index对select语句的性能影响分析

1.搞清楚两种索引的概念 在比较两种索引对select产生的影响之前,先要搞清楚,什么是Local prefixed index,什么叫Local nonprefixed index.其实,这两种索引,都是属于分区local索引,所以,这两种类型的索引,只有可能在分区表上才会出现. 1.1 什么是Local prefixed index 是指索引中的列,就是分区表的分区键列,或者是索引中的列,包含表的分区键值列,并且为前置位 置在索引最前部位置的本地分区索引. 例如,emp表是按时间范围分区的表

在用 <%@include file="date.jsp" %> "date.jsp"老提示出错,错误为: Multiple annotations found at this line: - Duplicate local variable path - Duplicate local variable basePath 该怎么解决呢?

重复变量 date.jsp文件内部不应该再出现重复的变量定义 也就是<%@include%>是先把文件源代码一模一样的拷贝过来,然后才开始编译 所以如果有相同的变量肯定报错 用了动态的<jsp: include file="top.jsp" />的就正确了 因为<%@include%>引进的是代码,把代码包含进来,而新进JSP时,会默认生成 <% String path = request.getContextPath(); String ba

werkzeug(flask)中的local,localstack,localproxy探究

1.关于local python中有threading local处理方式,在多线程环境中将变量按照线程id区分 由于协程在Python web中广泛使用,所以threading local不再满足需要 local中优先使用greenlet协程,其次是线程id,如下所示: try: from greenlet import getcurrent as get_ident except ImportError: try: from thread import get_ident except Im

flask 中的 werkzeug Local,LocalStack 和 LocalProxy 技术应用

什么是 Local wsgi 每次请求,会把过程进行抽离无状态话,过程数据存储在本次请求的全局变量中,使用到了Local. Local 作为每次请求的全局命令空间,属于每次请求的私有 LocalStack 与 Local 相似,在 Local 基础之上使用堆栈方式进行操作,管理 LocalProxy 代理类,代理 Local 或 LocalStack 实例 为什么使用 Local 为什么使用自定义 Local,而不是 threading.local.这是由内核决定的 1. web 应用在启动之后

Werkzeug之Local源码解析

Werkzeug之Local源码解析 原博客地址 http://liuyajing.coding.me/blogs/python/2018/werkzeug-local/ 一.引入 最近在阅读 Flask 的源码,遇到三个概念:Local . LocalStack 和 LocalProxy ,本文主要就针对 Local 概念及其源码进行原理剖析. 二.Local Local 是一个类,源码位置:site-packages/werkzeug/local.py 在模块的开头,有以下代码: # 由于每

Can&#39;t connect to local MySQL server through socket ‘/var/run/mysqld/mysqld.sock‘ (2)解决思路

首先说明一下mysql.sock文件的作用: 连接mysql有两种方式,第一种是TCP/IP,第二种就是直接使用unix domain socket,它比TCP/IP块. mysql.sock是在mysql-server和client在同一服务器上时,发起本地连接时可用,而无需定义-h参数指定具体的IP.mysql.sock是随每次mysql server启动时生成,通常配置参数是将mysql.sock生成在/tmp/目录下.即在/etc/my.cnf文件中指定socket=/tmp/mysql