Pergunta

Agora eu tenho um script mod_wsgi que está estruturado como este ..

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]

Eu queria saber se alguém sabe de uma maneira de mudar isso para operar numa base yield vez de return, de que maneira eu posso enviar a página como está sendo gerado e não apenas uma vez que está completo, assim que o carregamento da página pode ir mais rápido para o usuário.

No entanto, sempre que eu trocar a saída para uma lista e deu-lo no aplicativo (), ele lança um erro:

TypeError: sequence of string values expected, value of type list found
Foi útil?

Solução

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

"No entanto, sempre que eu trocar a saída para uma lista e deu-lo no aplicativo (), ele lança um erro:"

Bem, não deu a lista. Rendimento de cada elemento em vez disso:

for part in mylist:
    yield part

ou se a lista é o conteúdo inteiro, apenas:

return mylist

Como a lista já é um iterador e pode produzir por si só.

Outras dicas

Note que 'rendimento' deve ser evitado, a menos que seja absolutamente necessário. Em particular 'rendimento' será ineficaz se obtendo-se lotes de pequenas cadeias. Isso ocorre porque a especificação WSGI exige que depois de cada corda concluiu que a resposta deve ser lavada. Para Apache / mod_wsgi, meios de lavagem cada cadeia a ser forçado para fora através do filtro e do sistema brigada balde saída Apache e para a tomada. Ignorando a sobrecarga do sistema Apache filtro de saída, escrevendo lotes de pequenas cordas em um soquete é simplesmente mau para começar.

Este problema também existe quando uma matriz de cadeias é retornado de uma aplicação como uma descarga também tem de ser realizada entre cada cadeia na matriz. Isto é porque a cadeia é tratada como um iterable e não uma lista. Assim, para uma lista pré-formado de cordas, é muito melhor para se juntar as cordas individuais em uma cadeia de grandes dimensões e retornar uma lista contendo apenas que uma string. Isso também permite uma implementação WSGI para gerar automaticamente um Content-Length para a resposta se não foi explicitamente previsto.

Apenas certifique-se de que, quando se juntar todas as cordas em uma lista em um, que o resultado é retornado em uma lista. Se isso não for feito e, em vez da string é devolvida, essa seqüência é tratada como uma iterable, onde cada elemento na string é uma única cadeia de caracteres. Isso resulta em um flush a ser feito depois de cada personagem, que vai ser ainda pior do que se as cordas não tinha sido unidas.

Não envie o comprimento de conteúdo e enviar a saída como você derivar dele. Você não precisa saber o tamanho da saída, se você simplesmente não fazer enviar o cabeçalho Content-Length. Dessa forma, pode enviar parte da resposta antes de ter calculado o resto.

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! -->"

Caso contrário, você terá nenhum benefício a partir do envio de pedaços, desde computar a saída é provavelmente a parte lenta e o protocolo de internet irá enviar a saída em pedaços de qualquer maneira.

Infelizmente, isso não funciona no caso em que, por exemplo, o cálculo de part2 () decide que você realmente precisa mudar um cabeçalho (como um cookie) ou necessidade de construir outras estruturas de dados da página global - se isso nunca acontece, você precisa calcular a saída inteira antes enviando os cabeçalhos, e poderia muito bem usar um return [output]

Por exemplo http://aaron.oirt.rutgers.edu/myapp/ docs / W1200_1200.config_template Precisa construir uma estrutura de dados global de página para os links para subseções que show no topo da página - por isso a última subseção deve ser processado antes do primeiro pedaço de saída é entregue ao cliente.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top