4

现在我有一个结构如下的 mod_wsgi 脚本..

def application(environ, start_response):
    status = '200 OK'
    output = 'Hello World!'

    response_headers = [('Content-type', 'text/plain'),
                    ('Content-Length', str(len(output)))]
    start_response(status, response_headers)

    return [output]

我想知道是否有人知道一种方法可以将其更改为在yield基础上操作而不是return,这样我就可以在页面生成时发送页面,而不仅仅是在完成后发送,因此页面加载对用户来说可以更快。

但是,每当我将输出交换为列表并在 application() 中生成它时,它都会引发错误:

TypeError: sequence of string values expected, value of type list found
4

3 回答 3

7
def application(environ, start_response):
    status = '200 OK'
    output = 'Hello World!'

    response_headers = [('Content-type', 'text/plain'),
                    ('Content-Length', str(len(output)))]
    start_response(status, response_headers)

    yield output

“但是,每当我将输出交换为列表并在 application() 中生成它时,它都会引发错误:”

好吧,不要产生列表。生成每个元素:

for part in mylist:
    yield part

或者如果列表是全部内容,只需:

return mylist

因为列表已经是一个迭代器并且可以自己产生。

于 2009-04-30T00:24:28.940 回答
7

请注意,除非绝对必要,否则应避免“屈服”。特别是如果产生大量小字符串,'yield' 将是低效的。这是因为 WSGI 规范要求在每个字符串产生后必须刷新响应。对于 Apache/mod_wsgi,刷新意味着每个字符串都被强制通过 Apache 输出桶旅和过滤系统并进入套接字。忽略 Apache 输出过滤器系统的开销,将大量的小字符串写入套接字简直是糟糕的开始。

当从应用程序返回字符串数组时也存在此问题,因为还必须在数组中的每个字符串之间执行刷新。这是因为字符串被视为可迭代而不是列表。因此,对于预先形成的字符串列表,最好将各个字符串连接成一个大字符串并返回一个仅包含该字符串的列表。这样做还允许 WSGI 实现自动为响应生成 Content-Length(如果没有显式提供)。

只需确保在将列表中的所有字符串合并为一个时,结果会在列表中返回。如果不这样做,而是返回字符串,则该字符串被视为可迭代的,其中字符串中的每个元素都是单个字符串。这会导致在每个字符之后都进行刷新,这将比没有连接字符串时更糟。

于 2009-06-24T11:31:38.113 回答
0

不要发送内容长度并在派生时发送输出。如果您根本不发送 Content-Length 标头,则无需知道输出的大小。这种方式可以在您计算其余部分之前发送部分响应。

def application(environ, start_response):
    status = '200 OK'
    output = 'Hello World!'

    response_headers = [('Content-type', 'text/html')]
    start_response(status, response_headers)

    yield head()
    yield part1()
    yield part2()
    yield part3()
    yield "<!-- bye now! -->"

否则,您将不会从块中发送任何好处,因为计算输出可能是缓慢的部分,并且互联网协议无论如何都会以块的形式发送输出。

遗憾的是,这在以下情况下不起作用,例如,part2() 的计算决定您确实需要更改标题(如 cookie)或需要构建其他页面全局数据结构 - 如果这种情况发生,您需要在发送标头之前计算整个输出,还不如使用return [output]

例如http://aaron.oirt.rutgers.edu/myapp/docs/W1200_1200.config_template 需要为显示在页面顶部的小节的链接构建页面全局数据结构——所以最后一个小节必须是在第一个输出块交付给客户端之前呈现。

于 2009-05-04T18:20:40.050 回答