官方url
http://webpy.org/cookbook/streaming_large_files.zh-cn
有关yield的说明
从python的yield说起 http://lukejin.iteye.com/blog/587051
[Python 学习]2.5版yield之学习心得 http://blog.donews.com/limodou/archive/2006/09/04/1028747.aspx
关于yield的写法
以上两篇文章的写法我都懂,但是看web.py里面这个例子的时候,还是看不懂
count_holder通过iframe里面的url,调了4次count_down
访问一次127.0.0.1:8080/,相当于接连访问了
127.0.0.1:8080/10
127.0.0.1:8080/9
127.0.0.1:8080/8
127.0.0.1:8080/7
4个url
所以继续看count_down的内容
count_down里有好几个yield
怎么能一口气就运行到底了呢?
后来才看见这句话
You can't mix basic string and Yield returns in the same method. If you use Yield, you'll have to use yield for everything because your function becomes a generator.
到此为止,个人理解,
1 用了yield就不能用return,yield相当于return + wait的关系
2 web.py会不断调用下面每个class的next方法,直到最后
做了个实验来证实
# Simple streaming server demonstration # Uses time.sleep to emulate a large file read import web import time urls = ( "/", "count_holder", "/down", "count_down", ) app = web.application(urls, globals()) class count_down: def GET(self,count): print 'count_down' class count_holder: def GET(self): web.header('Content-type','text/html') web.header('Transfer-Encoding','chunked') yield '1' print 'step1' yield '2' print 'step2' yield '3' print 'step3' if __name__ == "__main__": app.run()
运行 http://192.168.1.100:8080/ 后在控制台的结果果然是
step1
step2
step3
192.168.1.100:2069 - - [17/Feb/2012 22:09:38] "HTTP/1.1 GET /favicon.ico" - 200 OK
连放在yield下面的step3都打出来了真够可以。
最后结果,个人觉得比较实用的分块下载的例子是,很有java风格啊
http://www.cnblogs.com/QLeelulu/archive/2011/08/05/2128577.html
class download: def GET(self): file_name = 'file_name' file_path = os.path.join('file_path', file_name) f = None try: f = open(file_path, "rb") webpy.header('Content-Type','application/octet-stream') webpy.header('Content-disposition', 'attachment; filename=%s.dat' % file_name) while True: c = f.read(BUF_SIZE) if c: yield c else: break except Exception, e: print e yield 'Error' finally: if f: f.close()