gevent.local --Greenlet本地对象

Greenlet-本地对象。

此模块基于 `_threading_local.py`_ _来自Python3.4的标准库。

Greenlet本地对象支持对Greenlet本地数据的管理。如果您有希望成为greenlet本地的数据,只需创建greenlet本地对象并使用其属性:

>>> import gevent
>>> from gevent.local import local
>>> mydata = local()
>>> mydata.number = 42
>>> mydata.number
42

您还可以访问本地对象的字典:

>>> mydata.__dict__
{'number': 42}
>>> mydata.__dict__.setdefault('widgets', [])
[]
>>> mydata.widgets
[]

greenlet本地对象最重要的是,它们的数据是greenlet本地的。如果我们在不同的greenlet中访问数据:

>>> log = []
>>> def f():
...     items = list(mydata.__dict__.items())
...     items.sort()
...     log.append(items)
...     mydata.number = 11
...     log.append(mydata.number)
>>> greenlet = gevent.spawn(f)
>>> greenlet.join()
>>> log
[[], 11]

我们得到不同的数据。此外,在另一个greenlet中所做的更改不会影响在该greenlet中看到的数据:

>>> mydata.number
42

当然,从本地对象获得的值,包括 __dict__ 属性,用于读取属性时Greenlet的当前状态。出于这个原因,您通常不希望跨greenlet保存这些值,因为它们只适用于它们来自的greenlet。

您可以通过子类化本地类来创建自定义本地对象:

>>> class MyLocal(local):
...     number = 2
...     initialized = False
...     def __init__(self, **kw):
...         if self.initialized:
...             raise SystemError('__init__ called too many times')
...         self.initialized = True
...         self.__dict__.update(kw)
...     def squared(self):
...         return self.number ** 2

这对于支持默认值、方法和初始化很有用。请注意,如果定义 __init__ 方法,每次在单独的greenlet中使用本地对象时都将调用它。这对于初始化每个greenlet的字典是必要的。

现在,如果我们创建一个本地对象:

>>> mydata = MyLocal(color='red')

现在我们有了一个默认号码:

>>> mydata.number
2

初始颜色:

>>> mydata.color
'red'
>>> del mydata.color

以及对数据进行操作的方法:

>>> mydata.squared()
4

和以前一样,我们可以在单独的greenlet中访问数据:

>>> log = []
>>> greenlet = gevent.spawn(f)
>>> greenlet.join()
>>> log
[[('color', 'red'), ('initialized', True)], 11]

在不影响Greenlet数据的情况下:

>>> mydata.number
2
>>> mydata.color
Traceback (most recent call last):
...
AttributeError: 'MyLocal' object has no attribute 'color'

注意,子类可以定义槽,但它们不是greenlet本地的。它们在绿叶树间共享:

>>> class MyLocal(local):
...     __slots__ = 'number'

>>> mydata = MyLocal()
>>> mydata.number = 42
>>> mydata.color = 'red'

因此,单独的绿let:

>>> greenlet = gevent.spawn(f)
>>> greenlet.join()

影响我们看到的:

>>> mydata.number
11
>>> del mydata

在 1.1a2 版更改: 更新实现以匹配python 3.4而不是python 2.5。这导致当地人一离开绿地就有资格收集垃圾。

在 1.2.3 版更改: 使用弱引用清除我们建立的greenlet链接,以防本地对象在greenlet之前死亡。

在 1.3a1 版更改: 直接实现属性访问的方法,直接在这里处理描述符。这允许删除锁的使用,并大大提高了性能。

在 1.3a1 版更改: 这个 __init__ 子类方法 local 不再使用锁定调用。cpython在其本机实现中不使用这样的锁。如果在中使用多个依赖属性的代码 __slots__ (在所有greenlet中共享)开关 __init__ .

class local(*args, **kw)[源代码]

基类:object

属性为greenlet local的对象。

Next page: gevent.lock --锁定原语