Monthly Archives: 8月 2013

You are browsing the site archives by month.

私がPython3でUnicodeEncodeErrorなのはどう考えてもデフォルト文字コードが悪い!

python_logo

とまぁわかりにくいタイトルですね。
要は「よーしパパ、Python3でCGIやっちゃうぞー」って意気込んだは良いけど
出力するソースに日本語を含んだ途端に
UnicodeEncodeError: ‘ascii’ codec can’t encode characters
なんて文字列に阻まれたりするんですよーってことです(´・ω・`)
(それ以前のパーミッション設定とか注意は サーバーでPythonを使うときに注意すること を参考に)

このエラーを理解するには、Python2.x系と違って
Unicodeとはなんぞやー?とかbyte列とはなんぞやー?とか色々知る必要があるらしい。
あと、Pythonはデフォルト設定をよく読みに行くらしいという特性も知らないと躓きそうです;
正直、僕みたいな文系プログラマーにはわかりにくかったです(ノд`)+゜。

で、結局注意点は
・Pythonのソースコードは基本的にUTF-8で書こうぜ
・一応2行目に # -*- coding: utf-8 -*- みたいにソースのエンコードを指定しようね
・ファイルやフォームからの入出力の際は、必ずエンコード指定しろよー
・レンタルサーバとかにUPしたら、デフォルトエンコードを参考にしちまうみたいだから
 必要に応じて書き換えようぜー

って感じらしい(・ω・)

調べれば調べるほど訳のわからないことをして遠回りしたけど、
結局はこんな感じでデフォルトエンコーディングを書き換えることで日本語表示できましたー

import sys
import io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')

ちなみにサーバのデフォルトエンコーディングが何かを調べるには

import sys
print(sys.stdout.encoding) # ANSI_X3.4-1968 等を出力

のようにして調べると良いらしい。

とにかく文字コードだけで分厚い本になるぐらい難しい分野だと言われてることだけは
改めてよーくわかりました!(ノ∀`)
でもPythonプログラムを続けるためには、「わからないなりにでも前に進んでる実感がある!」
っていうのが大事だと思うんだ。それは文系プログラマーの大切なモチベーションだからね!

参考サイト
UnicodeEncodeError: に悩まされない。Python2.x から Python3.x への乗り換え
Dive Into Python 3 – 第4章.文字列

文字列の書式指定を使ってHTMLに変数を埋め込む

python_logo

HTMLの中に変数を入れ込むというCGIで良くやるやつです。
ソースはpython3.3を想定して書いてます。

結論から言えば、str.format() を使うだけです。

例えばPHPとかだと

$hello = 'こんにちは!';
print "<p>$hello</p>";
<p>こんにちは!</p>

となる。

これをPythonでやってみる。

hello = 'こんにちは!'
print('<p>' + hello + '</p>')
<p>こんにちは!</p>

んで、そのうちコメント(ヒアドキュメント)とprintf的な書き方を使ったりし始めてー

title = '挨拶は元気よく'
hello = 'こんにちは!'
print('''
<div>
    <h1>%s</h1>
    <p>%s</p>
</div>
''' % title, hello)
<div>
    <h1>挨拶は元気よく</h1>
    <p>こんにちは!</p>
</div>

とまぁここまでなら特に問題ないと思うけど、この書き方だと

1.変数を表示したい順番に並べなければいけない(% title, hello の部分)
2.埋め込まれた箇所を見てどの変数が入っているかわからない(どこを見ても%sだらけに)
 →何番目の変数か数えなきゃいけない!(>’A`)>

やりたいことは
・変数名でそのまま埋め込んで展開したい
・変数名をキーにした辞書(ディクショナリ)で管理したい

ということで解決策は「str.format() メソッドを使う」こと(・ω・)b
一目瞭然ソースを見てみる

greeting = {
    'goodmorning' : 'おはよう!',
    'hello' : 'こんにちは!',
    'goodevening' : 'こんばんは!'    
}
print('''
<p>
    {goodmorning}<br />
    {hello}<br />
    {goodevening}
</p>
'''.format(**greeting))
<p>
    おはよう!<br />
    こんにちは!<br />
    こんばんは!
</p>

辞書を別ファイルにしてインポートする形にすると
色々管理しやすくて良いですね(*´-`)