如何使用gevent本地模块

时间:2015-08-13 21:05:38

标签: python python-2.7 gevent

我试图使用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/omerholzinger/.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/omerholzinger/.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

我在这里缺少什么?谢谢!

1 个答案:

答案 0 :(得分:2)

因为你在函数data中声明变量foo(),它将被识别为一个不能在另一个函数中使用的局部变量。

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

<强>代码

#!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中的局部变量,而无需再次将其声明为局部变量。

希望它有所帮助。

修改后的代码

#!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()