みんなのPython Webアプリ編がPDFで無料公開されていますが、この本はPython 2.x向けに書かれているので、3.xではそのまま動かない点がチラホラ・・・
とりあえずChapter04を読んでみたところ、以下のような変更が必要です。
CGIHTTPServer -> http.server
3.xでは、標準ライブラリが整理され、名前が変わっている場合があります。
#2.x import CGIHTTPServer CGIHTTPServer.test() #3.x import http.server http.server.test(HandlerClass=http.server.CGIHTTPRequestHandler)
文字列リテラル
3.xではコーテーションで囲ったものが、2.xでいう文字列を表すようになりました。
#2.x greeting_string = u"Hello 世界" #3.x greeting_string = "Hello 世界"
なお、ファイルの2行め(エンコーディング指定の次の行に)に、from __future__ import unicode_literals
追加すると、2.xでも3.xと同じ扱いになります。
#encoding: shift-jis from __future__ import unicode_literals greeting_string = "Hello 世界"
また, 2.xでにおけるunicode関数は, 3.xではstrという名前になっています。
print文 -> print関数
#2.x print something #3.x print(something)
バイト列を出力 -> 文字列を出力し、自動変換
一番クリティカルな変更です。
2.xのprint文は、バイト列(2.xのstr)を受け取るのが基本で、unicodeは明示的にバイト列に変換することになります。
一方、3.xのprint関数はユニコード文字列(3.xのstr)を受け取るのが基本で、2.xのつもりでバイト列を渡しても期待した動作にはなりません。
#2.x print(u"あ".encode("cp932")) #-> あ #3.x print("あ".encode("cp932")) #-> b'\x82\xa0'
2.xでは .encode("utf-8")、.encode("shift-jis")などとすることで、出力するHTMLのエンコーディングを変更出来たのですが、
3.xではこのテクニックは使えず、出力のエンコーディングはsys.stdout.encodingに固定です。
では、3.xではどうすれば良いかというと、sys.stdoutの値自体を変えてしまえば良いのです。
#3.x import sys import io sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') print("あ") #自動でutf-8にエンコードされて出力される
元に戻すには、sys.__stdout__に本来のsys.stdoutが保存されているので、これを再代入します。
#3.x import sys sys.stdout = sys.__stdout__