1

web.py セットアップ用に次の 2 つのハンドラーがあります。

class count1:
    def GET(self):
        s.session.count += 1
        return str(s.session.count)

class count2:
    def GET(self):
        s.session.count += 1
        yield str(s.session.count)

アプリは web.py 出荷の cherrypy (app.run()) または gevent サーバーで実行されます。

urls = (
    "/count1", "count.count1",
    "/count2", "count.count2",
)

session = web.session.Session(app, web.session.DiskStore('sessions'), initializer={'count': 0})
s.session = session
app = web.application(urls, locals())

print "Main: setting count to 1"    

from gevent.wsgi import WSGIServer
if __name__ == "__main__":
    usecherrypy = False
    if usecherrypy:
        app.run()
    else: # gevent wsgiserver
        wsgifunc = app.wsgifunc()
        server = WSGIServer(('0.0.0.0', 8080), wsgifunc, log=None)
        server.serve_forever()

セッションは count1 の場合は正常に機能しますが、count2 の場合は常に機能するとは限りません。/count2 のページが最初に読み込まれると、カウンターは 1 回増加しますが、その後更新してもセッションのカウンターは増加しません。つまり、セッションへの更新は保存されません。ここで何が間違っているでしょうか?

この場合、pypi からインストールされた Webpy または github から最新の Webpy は同じように動作します。

コードを掘り下げた後、実際の理由は、ハンドラーがyieldを使用している場合、ジェネレーターオブジェクトを返すためにのみ呼び出され、その後、すべての囲んでいるプロセッサーから返されるためです(たとえば、finallyで_saveを呼び出すSession._processor)ブロック)。Web.py は、データをクライアントに返す前にジェネレーターが完全にアンロールされていることを確認しますが、アンロール プロセスはすべてのプロセッサの後であり、通常の関数ハンドラーとはまったく異なる動作です。

したがって、質問は次のとおりです:これに対する修正または回避策(Session._saveを手動で呼び出す以外)はありますか?

ご回答ありがとうございます。

4

1 に答える 1

0

yield が値ではなくジェネレーターを返すために発生する可能性があります。

参照:

http://od-eon.com/blogs/calvin/python-yield-versus-return/

Pythonで「yield」キーワードは何をしますか?

于 2013-06-15T17:04:20.690 に答える