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__
.