On 06/16/2010 02:03 PM, Jérôme Mainka wrote: > Hello, > > I try to experiment with coroutines and I don't understand why this > snippet doesn't work as expected... In python 2.5 and python 2.6 I get > the following output: > > 0 > Exception exceptions.TypeError: "'NoneType' object is not callable" in > <generator object at 0x7e43f8> ignored > > The TypeError exception comes from the pprint instruction... > > If i replace the main part with: > > == > p1 = dump() > p2 = sort(p1) > for item in my_list: p2.send(item) > == > > it works as expected.
What a strange problem. I hope somebody else can shed more light on what is going on Anyway, it appears (to me) to be a scoping issue: if you move "from pprint import pprint" into the dump() function body, it works. I don't understand why this changes anything: pprint was in the global namespace all along, and it's present and functioning exactly *once*, after which it's None. It's still there, otherwise there'd be a NameError, but it was set to None without any line of code doing this explicitly as far as I can see. Another VERY strange thing is, of course, your "fix": renaming "p" to "p2" helps. "p", "p1", "p3", and "yyy" are just some examples of variable names that don't work. As for Python versions: I changed the code to work with Python 3 and get the same odd behaviour. > > I don't understand what is goind wrong. Has someone an explanation for > this issue? > > Thanks, > > Jérôme > > > === > from functools import wraps > from pprint import pprint > import random > > def coroutine(f): > @wraps(f) > def start(*args, **kwargs): > res = f(*args, **kwargs) > res.next() > return res > return start > > @coroutine > def sort(target): > l = [] > > try: > while True: > l.append((yield)) > except GeneratorExit: > l.sort() > for item in l: > target.send(item) > > @coroutine > def dump(): > while True: > pprint((yield)) > > if __name__ == "__main__": > my_list = range(100) > random.shuffle(my_list) > > p = sort(dump()) > > for item in my_list: > p.send(item) -- http://mail.python.org/mailman/listinfo/python-list