如何使用gevent本地模块

how to use gevent local module

我正在尝试使用 gevent.local 模块来获得 greenlet 上下文。 按照以下示例:http://www.gevent.org/gevent.local.html 我试过这个示例代码:

#!env python

import gevent
from gevent import local

def foo():
    print("IN FOO")
    data = local.local()
    data.numbers = 42

    bar()

def bar():
    print("IN BAR")
    data = local.local()
    print(data.numbers)


def main():
    foo_gl = gevent.Greenlet(foo)
    print("starting foo")
    foo_gl.start()
    gevent.joinall([foo_gl])

if __name__ == "__main__":
    main()

但是我得到一个错误:

$ mytest/local.py
starting foo
IN FOO
IN BAR
Traceback (most recent call last):
  File "/Users/me/.virtualenvs/sorites/lib/python2.7/site-packages/gevent/greenlet.py", line 327, in run
    result = self._run(*self.args, **self.kwargs)
  File "gl_test/local.py", line 11, in foo
    bar()
  File "gl_test/local.py", line 16, in bar
    print(data.numbers)
  File "/Users/me/.virtualenvs/sorites/lib/python2.7/site-packages/gevent/local.py", line 186, in __getattribute__
    return object.__getattribute__(self, name)
AttributeError: 'local' object has no attribute 'numbers'
<Greenlet at 0x1053b2410: foo> failed with AttributeError

我在这里错过了什么?谢谢!

因为你在函数foo()中声明了变量data,它会被识别为局部变量,不能在其他函数中使用。

而函数bar()中声明的变量data是另一个局部变量,与函数foo()中声明的变量data无关

代码

#!env python

import gevent
from gevent import local

def foo():
    print("IN FOO")
    data = local.local()
    #This line of code declares data as a local variable.
    data.numbers = 42

    bar()

def bar():
    print("IN BAR")
    data = local.local()
    #This line of code declares data as an another local variable.
    print(data.numbers)


def main():
    foo_gl = gevent.Greenlet(foo)
    print("starting foo")
    foo_gl.start()
    gevent.joinall([foo_gl])

if __name__ == "__main__":
    main()

以下是显示 gevent.local 模块如何工作的代码。

你可以发现,即使变量data声明为全局变量,当你在另一个greenlet中修改同一个变量时,它也不会在一个greenlet中受到影响。这意味着您可以在每个 greenlet 中将该变量用作局部变量,而无需再次将其声明为局部变量。

希望对您有所帮助。

修改代码

#!env python

import gevent
from gevent import local

data = local.local()
data.numbers = 12
#Declare data as a global variable.

def foo():
    print("IN FOO")
    data.numbers = 42
    #Change the value of data.numbers.

    print(data.__dict__)
    #Check the values in data in the function foo.

def bar():
    print("IN BAR")

    print(data.__dict__)
    #Check the values in data in the function bar.


def main():
    print("In Main")
    print(data.__dict__)
    #Check the values in data at beginning.

    foo_gl = gevent.Greenlet(foo)
    bar_gl = gevent.Greenlet(bar)
    foo_gl.start()
    bar_gl.start()
    gevent.joinall([foo_gl, bar_gl])

    print("Afeter all, In Main")
    print(data.__dict__)
    #Check the values in data at the end.

if __name__ == "__main__":
    main()