I'm trying to use gevent.local module to have a greenlet context. Following the example in: http://www.gevent.org/gevent.local.html I tried this sample code:
#!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()
But I get an error:
$ 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
What am I missing here? Thanks!
Because you declare the variable data
in the function foo()
, it will be recognized as a local variable which can not be used in another function.
And the variable data
declared in the function bar()
is an another local variable, which has nothing to do with the variable data
declared in the function foo()
Code
#!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()
The following is the code which shows that how the gevent.local
module works.
You can find out that even the variable data
is declared as a global variable, it will not be affected in one greenlet when you modified the same variable in another greenlet. That means you can use the variable as a local variable in each greenlet without declaring it as a local variable again.
Hope it helps.
Modified Code
#!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()