PEP 342: Add more examples based on ideas stolen from an early version of
PEP 288. Also add some more explanation of the 'throw()' name, also stolen from PEP 288. :)
This commit is contained in:
parent
c97e46d034
commit
e149a9dcbc
85
pep-0342.txt
85
pep-0342.txt
|
@ -247,6 +247,18 @@ Specification: Exceptions and Cleanup
|
|||
supplied, must be a valid Python traceback object, or a TypeError
|
||||
occurs.
|
||||
|
||||
Note: The name of the throw() method was selected for several
|
||||
reasons. Raise is a keyword and so cannot be used as a method
|
||||
name. Unlike raise (which immediately raises an exception from the
|
||||
current execution point), throw() first resumes the generator, and
|
||||
only then raises the exception. The word throw is suggestive of
|
||||
putting the exception in another location, and is already associated
|
||||
with exceptions in other languages.
|
||||
|
||||
Alternative method names were considered: resolve(), signal(),
|
||||
genraise(), raiseinto(), and flush(). None of these seem to fit
|
||||
as well as throw().
|
||||
|
||||
New standard exception: GeneratorExit
|
||||
|
||||
A new standard exception is defined, GeneratorExit, inheriting
|
||||
|
@ -358,7 +370,76 @@ Open Issues
|
|||
|
||||
Examples
|
||||
|
||||
1. A simple co-routine scheduler or "trampoline" that lets
|
||||
1. A simple "consumer" decorator that makes a generator function
|
||||
automatically advance to its first yield point when initially
|
||||
called:
|
||||
|
||||
def consumer(func):
|
||||
def wrapper(*args,**kw):
|
||||
gen = func(*args, **kw)
|
||||
gen.next()
|
||||
return gen
|
||||
wrapper.__name__ = func.__name__
|
||||
wrapper.__dict__ = func.__dict__
|
||||
wrapper.__doc__ = func.__doc__
|
||||
return wrapper
|
||||
|
||||
2. An example of using the "consumer" decorator to create a
|
||||
"reverse generator" that receives images and creates thumbnail
|
||||
pages, sending them on to another consumer. Functions like
|
||||
this can be chained together to form efficient processing
|
||||
pipelines of "consumers" that each can have complex internal
|
||||
state:
|
||||
|
||||
@consumer
|
||||
def thumbnail_pager(pagesize, thumbsize, destination):
|
||||
while True:
|
||||
page = new_image(pagesize)
|
||||
rows, columns = pagesize / thumbsize
|
||||
pending = False
|
||||
try:
|
||||
for row in xrange(rows):
|
||||
for column in xrange(columns):
|
||||
thumb = create_thumbnail((yield), thumbsize)
|
||||
page.write(
|
||||
thumb, col*thumbsize.x, row*thumbsize.y
|
||||
)
|
||||
pending = True
|
||||
except GeneratorExit:
|
||||
# close() was called, so flush any pending output
|
||||
if pending:
|
||||
destination.send(page)
|
||||
|
||||
# then close the downstream consumer, and exit
|
||||
destination.close()
|
||||
return
|
||||
else:
|
||||
# we finished a page full of thumbnails, so send it
|
||||
# downstream and keep on looping
|
||||
destination.send(page)
|
||||
|
||||
@consumer
|
||||
def jpeg_writer(dirname):
|
||||
fileno = 1
|
||||
while True:
|
||||
filename = os.path.join(dirname,"page%04d.jpg" % fileno)
|
||||
write_jpeg((yield), filename)
|
||||
|
||||
|
||||
# Put them together to make a function that makes thumbnail
|
||||
# pages from a list of images and other parameters.
|
||||
#
|
||||
def write_thumbnails(pagesize, thumbsize, images, output_dir):
|
||||
pipeline = paginate(
|
||||
pagesize, thumbsize, jpeg_writer(output_dir)
|
||||
)
|
||||
|
||||
for image in images:
|
||||
pipeline.send(image)
|
||||
|
||||
pipeline.close()
|
||||
|
||||
3. A simple co-routine scheduler or "trampoline" that lets
|
||||
coroutines "call" other coroutines by yielding the coroutine
|
||||
they wish to invoke. Any non-generator value yielded by
|
||||
a coroutine is returned to the coroutine that "called" the
|
||||
|
@ -437,7 +518,7 @@ Examples
|
|||
|
||||
self.queue.append(resume)
|
||||
|
||||
2. A simple "echo" server, and code to run it using a trampoline
|
||||
4. A simple "echo" server, and code to run it using a trampoline
|
||||
(presumes the existence of "nonblocking_read",
|
||||
"nonblocking_write", and other I/O coroutines, that e.g. raise
|
||||
ConnectionLost if the connection is closed):
|
||||
|
|
Loading…
Reference in New Issue