On Thu, 30 Sep 2004, Phillip J. Eby wrote: ... > A mechanism to pass values or exceptions into generators [ Possibly somewhat off topic, and apologies if it is, and I'm positive someone's done something similar before, but I think it's relevant to the discussion in hand -- largely because the above use case *doesn't* require changes to python... ] A minimal(ish) example of a technique for doing this I presented last week at a streaming workshop looked like the following. (amongst other stuff...) Create a decorator that wraps the generator inside a class, derived from a supplied base class. (default to object) import copy def wrapgenerator(bases=object, **attrs): def decorate(func): class statefulgenerator(bases): __doc__ = func.__doc__ def __init__(self,*args): super(statefulgenerator, self).__init__(*args) self.func=func(self,*args) for k in attrs.keys(): self.__dict__[k] = copy.deepcopy(attrs[k]) self.next=self.__iter__().next def __iter__(self): return iter(self.func) return statefulgenerator return decorate Create a class to handle the behaviour you wish to use to communicate with the generator from outside: class component(object): def __init__(self, *args): # Default queues self.queues = {"inbox":[],"control":[],"outbox":[],"signal":[]} def send(self, box, object): self.queues[box].append(object) def dataReady(self,box): return len(self.queues[box])>0 def recv(self, box): # NB. Exceptions aren't caught X=self.queues[box][0] del self.queues[box][0] return X Then just use something like this: @wrapgenerator(component) def forwarderNay(self): "Simple data forwarding generator" while 1: if self.dataReady("inbox"): self.send("outbox",self.recv("inbox")+"Nay") elif self.dataReady("control"): if self.recv("control") == "shutdown": break yield 1 self.send("signal","shutdown") yield 0 In conjuction with a simplistic scheduler, and linkage functions this allows you to have something similar to CSP. I've come to the conclusion recently that the fact you can't* yield across multiple levels is actually beneficial because it encourages you to use many small components. Used standalone you can do this though: f=forwarderNay() for word in ["hello", "world", "test"]: f.send("inbox", word) f.next() print f.recv("outbox"), print Which of course outputs: * helloNay worldNay testNay For small scale things this amount of cruft is a bit of a pain. We're using *essentially* this approach to build network servers and it seems a rather satisfying way of doing so TBH. (not exactly this approach so if this looks odd, that's why - I'm not allowed to release the source for precisely what we're doing :-( but the above I was on the slides I *was* able to talk about... :-) Hope that's of some use... Best Regards, Michael.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4