画面ごとにpyファイルを分けるときの注意点

GAEのドキュメントの「スタートガイド」に出てくる、おなじみのミニマムコード。

from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app

class MainPage(webapp.RequestHandler):
  def get(self):
    self.response.headers['Content-Type'] = 'text/plain'
    self.response.out.write('Hello, webapp World!')

application = webapp.WSGIApplication(
                                     [('/', MainPage)],
                                     debug=True)
def main():
  run_wsgi_app(application)

if __name__ == "__main__":
  main()

一方こちらは、GoogleAppEngineLauncher や、AptanaからGAEの新規プロジェクトを作る際の雛形として使われるミニマムコード。(これは、GAEインストール先の配下、new_project_templateというフォルダの下にmain.pyという名前で存在する)

import wsgiref.handlers
from google.appengine.ext import webapp

class MainHandler(webapp.RequestHandler):

  def get(self):
    self.response.out.write('Hello world!')

def main():
  application = webapp.WSGIApplication([('/', MainHandler)],
                                       debug=True)
  wsgiref.handlers.CGIHandler().run(application)

if __name__ == '__main__':
  main()

似てるようで少し違うこの2つのコードであるが、前者に肉付けしていったほうが、後々幸せになれる。
この事は、2つ画面を作って、メイン画面からサブ画面に遷移する、という処理を試していたときに気づいた。自分は、後者の雛形に肉付けする形でコードを書いていた。

スタートガイドを参考にして、class MainForm と class SubForm を定義して、MainForm を起動して、submit ボタン押したら SubForm へ遷移させる、という動作をさせることには成功した。ただ、実際の開発現場においては、1本のソースファイルにすべての処理を詰め込むなんてことはしないので、試しに class SubForm を別のpyファイルに外出ししてみたのだが、遷移できなくなってしまった。理由は、getやpostをハンドリングする application というオブジェクトが、def main() 内のローカルスコープとなっているために、main()を抜けると、ハンドリングする人がいなくなってしまうのが原因であった。前者のように、applicationオブジェクトの宣言を、main()の外に書いたら遷移できるようになった。

テンプレートを用意してくれるのはいいが、中身は前者にしてくれればいいのに・・・
当初、前者と後者では何が違うんだろうと思いつつも、main()の前に処理があるのに違和感を感じて、後者の雛形を選んだのだが、そのおかげで意味がわかってよかったのだが。