Werkzeug - 本地上下文(context locals)

官方文档原文
你迟早会遇到这种情况,在单个视图函数或者帮助函数中需要调用一些变量。PHP是通过全局变量来实现的。但是在一个WSGI(网页服务器网管接口)应用中不能通过全局变量来实现,因为只要你调用了全局命名空间,那么应用的线程安全就没法保证了。
Python的标准库里有个概念,叫作线程本地变量(或线程本地变量数据)。线程本地变量是全局对象,可以向其中添加一些东西,然后以线程安全(thread-safe)、线程私有(thread-specific)的方式取出。也就是说你可以在任何时候对一个线程本地变量对象添加数据、取数据,这个线程本地变量记录了当前所在的线程,并且检索该线程对应的值(如果该线程存在)。这样,你就不会获取到另一个线程的数据了。
然而,这种方法有一些弊端。例如,在Python中除了线程之外还会有其他类型的并发。最常见的一个就是greenlet。并且WSGI并不保证每个请求都只需要获取自己的线程。可能会出现这种情况,一个请求需要利用前一个请求的线程,所以在线程本地变量对象中的数据是需要被遗留的。
Werkzeug提供了一个本地数据存储的实现方式,叫作werkzeug.local。这个方法为线程本地变量提供了一个简单的功能,同时支持greenlet
下面是一个使用werkzeug.local的简单例子:

from werkzeug.local import Local, LocalManager

local = Local()
local_manager = LocalManager([local])

def application(environ, start_response):
    local.request = request = Request(environ)
    ...

application = local_manager.make_middleware(application)

代码将请求绑定到local.request。在同一上下文中,经过声明之后,每一处代码都可以安全的连接local.request,并且获取同一个请求对象。作用在本地管理器(local manager)上的make_middleware方法确保所有对本地对象的引用在请求过后都被清理干净。同一上下文这里指同一线程、进程中的同一greenlet(如果使用greenlet的话)。
如果一个请求没有被设置到本地对象上,当你试图连接本地对象时就会报AttributeError错误。可以使用getattr函数来避免:

def get_request():
    return getattr(local, 'request', None)

示例代码将返回请求对象,如果请求不可用将返回None
注意,本地对象并不能管理自己,所以需要本地管理器。你可以向本地管理器传递多个本地对象或将本地对象添加到manager.locals,每一次管理器清理的时候都会清理当前上下文中所有本地变量的数据。

werkzeug.local.release_local(local)
    释放当前上下文中本地变量的内容。使不用管理器的情况下调用本地变量成为可能。
    例如:

>>> loc = Local()
>>> loc.foo = 42
>>> release_local(loc)
>>> hasattr(loc, 'foo')
False

    通过这个函数可以释放LocalLocalStack对象。
    但是这种方法并不能释放代理(proxy)中的数据,因为这种方法为了释放本地变量需要保留对潜在本地变量的引用。
    v0.6.1新增

class werkzeug.local.LocalManager(locals=None, ident_func=None)
    本地对象并不能管理自己,所以需要本地管理器。你可以向本地管理器传递多个本地对象或将本地对象添加到manager.locals,每一次管理器清理的时候都会清理当前上下文中所有本地变量的数据。
    ident_func

你可能感兴趣的:(werkzeug,-,WSGI工具集的函数库,werkzeug,python)