Pythonにはいくつかの怠惰な実装があることを知っているので、Pythonで循環プログラミングを使用できるかどうか疑問に思いました。
そうでない場合、なぜですか?
共再帰ではなく、コルーチンを意味していると思います。はい、Pythonでは完全に可能です。PEP342:拡張ジェネレーターを介したコルーチンが実装されているからです。
正規の例は、コンシューマデコレータです。
def consumer(func):
def wrapper(*args,**kw):
gen = func(*args, **kw)
next(gen)
return gen
wrapper.__name__ = func.__name__
wrapper.__dict__ = func.__dict__
wrapper.__doc__ = func.__doc__
return wrapper
そのようなものを使用consumer
して、パイプラインとして機能し、フィルターをチェーンして情報をフィルターにプッシュしましょう。
from itertools import product
@consumer
def thumbnail_pager(pagesize, thumbsize, destination):
while True:
page = new_image(pagesize)
rows, columns = pagesize / thumbsize
pending = False
try:
for row, column in product(range(rows), range(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)
fileno += 1
# 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 = thumbnail_pager(
pagesize, thumbsize, jpeg_writer(output_dir)
)
for image in images:
pipeline.send(image)
pipeline.close()
中心的な原則はPythonジェネレーターであり、式を生成します。後者は、ジェネレーターが呼び出し元から情報を受信できるようにします。
編集:ああ、共再帰は確かに別の概念です。ウィキペディアの記事では、例としてPythonを使用しており、さらにPythonジェネレーターを使用していることに注意してください。
やってみましたか?
def a(x):
if x == 1: return
print "a", x
b(x - 1)
def b(x):
if x == 1: return
print "b", x
a(x - 1)
a(10)
ちなみに、Pythonには末尾再帰がなく、これは失敗しx > 1000
ます(ただし、この制限は構成可能です)