web.py笔记 大块文件下载

 

官方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都打出来了真够可以。

 

 

 写道
题外话,为啥我试验用的例子专门把
"/(.*)", "count_down",
改成
"/down", "count_down",


还是web.py官方例子坑爹

"/"和"/(.*)"的正则,都对http://192.168.1.100:8080/这个url有效
结果可能是因为"/"在上面的关系,所以"/"对应的count_holder优先吧

不改的话,访问http://192.168.1.100:8080/ 控制台出来的结果
step1
step2
step3
count_down
192.168.1.100:2090 - - [17/Feb/2012 22:12:24] "HTTP/1.1 GET /favicon.ico" - 200 OK

 

 

最后结果,个人觉得比较实用的分块下载的例子是,很有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()
 

你可能感兴趣的:(python)