In [17]:
def countdown(n):
print '> counting down from {}'.format(n)
while n > 0:
yield n
n -= 1
print ''
print '< countdown'
In [18]:
for n in countdown(10):
print n,
generator 함수를 호출하는것은 generator 객체를 생성하는것이지 함수를 실행하는 것이 아님generator.next() 를 호출하면 함수가 실행되고, yield 를 통해서 값을 생성하고, 함수의 실행을 잠시 중단하고, .next() 호출을 통해 실행을 재개한다. generator 가 리턴하면, iteration 은 멈춘다.
In [26]:
# calling generator fucntion creates the generator object not start the function
x = countdown(3)
print x
# call `.next()` starts generator object.
print x.next()
print x.next()
print x.next()
print x.next()
In [32]:
import os
print os.getcwd()
In [37]:
"""
generator 강의자료에 run/foo/xxx 등이 있는데 거기에 있는걸 복사해서 실행환경을 만들면 됨
"""
# follow.py
#
# Follow a file like tail -f.
import time
def follow(thefile):
thefile.seek(0,2)
while True:
line = thefile.readline()
if not line:
time.sleep(0.1)
continue
yield line
# Example use
# Note : This example requires the use of an apache log simulator.
#
# Go to the directory run/foo and run the program 'logsim.py' from
# that directory. Run this program as a background process and
# leave it running in a separate window. We'll write program
# that read the output file being generated
#
#logfile = open("run/foo/access-log","r")
logfile = open(r'd:\work.python\python_async_stuffs\coroutine_www.dabeaz.com\run\foo\access-log')
for line in follow(logfile):
print line,
In [40]:
def grep(pattern):
print 'looking for %s' % pattern
while True:
line = (yield)
if pattern in line:
print line,
In [47]:
g = grep("python")
g.next() # prime it!
g.send("hey!!")
g.send("welcome to koread")
g.send("wow python rocks!")
g.send("really?")
GeneratorExit 예외가 발생하니까 coroutine 에서 잡아준다.
In [55]:
def coroutine(func):
"""
"""
def start_coroutine(*args, **kwargs):
crtn = func(*args, **kwargs);
crtn.next()
return crtn
return start_coroutine
In [77]:
@coroutine
def grep(pattern):
print '[*] looking for %s' % pattern
try:
while True:
line = (yield)
if pattern in line:
print line,
except GeneratorExit as e:
print '\n[*] Going away, bye (gc or U called close())'
In [79]:
g = grep('python')
#g.next() # no need to call next()
g.send("hey!!")
g.send("welcome to koread")
g.send("wow python rocks!")
g.close()
In [83]:
g = grep('python')
g.send('wow! python is rock!')
g.send('wow! python is rock!')
g.send('wow! python is rock!')
g.throw(RuntimeError, "exception thrown")
In [85]:
# bogus.py
#
# Bogus example of a generator that produces and receives values
def countdown(n):
print "Counting down from", n
while n >= 0:
newvalue = (yield n)
# If a new value got sent in, reset n with it
if newvalue is not None:
n = newvalue
else:
n -= 1
# The holy grail countdown
c = countdown(5)
for x in c:
print x
if x == 5:
c.send(3)
In [13]:
import time
def coroutine(func):
"""A decorator function that takes care of starting a coroutine
automatically on call.
"""
def start(*args,**kwargs):
cr = func(*args,**kwargs)
cr.next()
#print 'coroutine started...'
return cr
return start
# data source
def follow(thefile, target):
thefile.seek(0, 2) # goto end of the file
while True:
line = thefile.readline()
if not line:
time.sleep(0.1)
continue
target.send(line) # 최초로 호출되는 시점에 객체(target)가 생성됨
# sink - a coroutine that receives data
@coroutine
def printer():
while True:
line = (yield)
print line
# useage
f = open(r'd:\work.python\python_async_stuffs\coroutine_www.dabeaz.com\run\foo\access-log')
#follow(f, printer) # 요거는 오류 남, 'AttributeError: 'function' object has no attribute 'send'
follow( f, printer() )
In [16]:
# data source
def follow(thefile, target):
thefile.seek(0, 2)
while True:
line = thefile.readline()
if not line:
time.sleep(0.1)
continue
target.send(line)
# filter
@coroutine
def grep(pattern, target):
while True:
line = (yield) # receive a line
if pattern in line:
target.send(line) # send to next stage
# sink - a coroutine that receives data
@coroutine
def printer():
while True:
line = (yield)
print line,
# useage
f = open(r'd:\work.python\python_async_stuffs\coroutine_www.dabeaz.com\run\foo\access-log')
follow( f, grep('python', printer()) )
In [ ]: