blogの引越しを考え中
なんつーか、使いづらい。
Hatena blog。
- ソースのカラー表示をしたい
- でも、はてなダイアリーは好みじゃない
だけで選んだんだけど、不満が募ってきた。
http://toc-gae-memo.blogspot.jp/ に引越しを画策中。
シンプルで自由度も高いのが決め手のポイントになってます。
ソースのカラー表示なんて機能、当たり前のようにない。
けど、css, javascript をワシャっと設定できるみたいなので、ソースのカラー表示も javascript でイケそうな予感がする。
もうひとつ。
ブログとは別にページを作成できる。
ブログの用途が
『自分の調べたことをまとめる』
なので、インデックスを作成できそうだ。
とはいえ、自由すぎる。
デザインや、ブログの投稿ルールをちょっと考えてみないとひどいことになりそうだ。
目下、一番の問題はこの Hatena blog にデータの Export 機能がないこと。
といっても、まだ件数も多くないから地道にやるべ。
絵文字ありのテキストファイルを処理する
ケータイメールのデータを処理するのに便利かな。
ポイントは codecs の encoding に 'shift_jis' ではなく 'mbcs' を指定する点。
#!/usr/bin/env python # -*- coding: utf-8 -*- import codecs def main(): # fin = codecs.open('sample.txt', 'r', 'shift_jis') # これでは encode 時にエラーが出る文字がある fin = codecs.open('sample.txt', 'r', 'mbcs') # こっちは正常に unicode 化される fout = codecs.open('out.txt', 'w', 'mbcs') # unicode から逆変換する for line in fin: print type(line) # 念のため line の型を調べる print >> fout, line, if __name__ == '__main__': main()
print type(line) の結果は、ちゃんと
<type 'unicode'>
だった。
python 2.7の日本語ヘルプを構築する
ウチの環境(Windows 7 SP1 x64)では、Pythonドキュメント日本語翻訳プロジェクトで配布されている htmlhelp(.chm) はエラーが表示されて正常に動作しない。
なので、ドキュメントソースから構築してみた。
以下、手順。
準備
- sphinxが必要。
- Mercurialが必要。
- HTML Help Workshopが必要。
python-doc-ja からソースを取得する
hg clone https://code.google.com/p/python-doc-ja/
でカレントディレクトリに python-doc-ja が作成され、ドキュメントソースがダウンロードされる。
ドキュメント作成に必要なユーティリティを取得する
cd python-doc-ja
で python-doc-ja に入り、
make checkout
を実行すると必要なユーティリティが python-doc-ja\tools にダウンロードされる。
設定を変更する
ヘルプファイルの表示で出るエラーを回避する
既存のヘルプファイルは copybutton.js を実行しようとしてエラーが発生する。
ヘルプファイルではあまり意味がないので、copybutton.js を読み込まないように変更する。
python-doc-ja\tools\sphinxext\layout.html
の {% block extrahead %} ブロックを以下のように変更する。
{% block extrahead %} <link rel="shortcut icon" type="image/png" href="{{ pathto('_static/py.png', 1) }}" /> {% if not embedded %} <script type="text/javascript" src="{{ pathto('_static/copybutton.js', 1) }}"></script> <script type="text/javascript" src="{{ pathto('_static/_jp.js', 1) }}"></script> {% endif %} {{ super() }} {% endblock %}
インデックスからの表示が失敗するエラーを回避する
インデックスからページを選択すると、ページがないという表示になる。
.hhk ファイル生成の問題を修正する。
python-doc-ja\tools\sphinx\sphinx\builders\htmlhelp.py
を変更する。
268~270 行目
elif len(refs) == 1: write_param('Local', refs[0]) else:
を
elif len(refs) == 1: # modify begin # write_param('Local', refs[0]) # modify change ref = refs[0] if isinstance(ref, tuple): ref = ref[1] write_param('Local', ref) # modify end else:
271 ~ 274 行目
for i, ref in enumerate(refs): # XXX: better title? write_param('Name', '[%d] %s' % (i, ref)) write_param('Local', ref)
を
for i, ref in enumerate(refs): # XXX: better title? # add begin if isinstance(ref, tuple): ref = ref[1] # add end write_param('Name', '[%d] %s' % (i, ref)) write_param('Local', ref)
htmlhelp を作成する
コマンドプロンプトから
make htmlhelp
を実行する。
しばらくすると、
python-doc-ja\build\htmlhelp
に python27ja1.chm が作成される。
エラーなく完了すれば、これで作業はおしまい。
ダイアモンド継承とsuper()の続きの続き
ずっと、どこかで
super() は継承元への型変換みたいな仕組みを提供してる
と思い込んでた。
これが大きな間違いのはじまり。
道理で、super()の文章を何度読んでも釈然としないわけだ。
動的な実行環境下での複数の継承の共同をサポートすることです。 この用途は Python 特有で、静的にコンパイルされる言語や、単一の継承しかサポートしない言語では見られないものです。 これは複数の基底クラスが同じメソッドを実装する “diamond diagram” を実装できるようにします。 良い設計のために、このメソッドがすべての場合に同じ形式で呼び出せるべきです。 (呼び出しの順序が実行時に決定されることや、順序がクラスの階層の変更に対応することや、その順序には実行時まで未知の兄弟クラスが含まれえることが理由です)
この文章の意味は、
super()は「適切」かつ「まんべんなく」上位クラスのメソッドを呼ぶための仕組みを一定の記述で提供する。 つまり、継承元の仕事をキッチリこなす。
ってことだ。
次の例のコードの動作でようやくわかった。
class A(object): def talk(self): print 'This is A.' class B(A): def talk(self): print 'This is B.' super(B, self).talk() class C(A): def talk(self): print 'This is C.' super(C, self).talk() class D(B, C): def talk(self): super(D, self).talk() def main(): d = D() d.talk() if __name__ == '__main__': main()
このとき、D.talk()では
super(D, self).talk()
だけを呼んでる。
その結果、
This is B. This is C. This is A.
となる。
ちゃんと継承元の talk() をまんべんなく呼び出してる。
呼び出しの重複もない。
道理で super() を説明するために、みんな __init__() で説明するわけだ。
__init__() とかは、こう動いて欲しいもん。
Python's Super is nifty, but you can't use itで説明されてる大事な話。
親クラスに super() を記述してないクラスがあると、そこでメソッドチェーンは途切れてしまう
という点は要注意。
最後に。
『特定のクラスの仕事だけしてくれ』ってときは、迷わず
C.talk(self)
でいいんだ。
ダイアモンド継承とsuper()の続き
super()の理解がまだ足りない
先程、【super()で C.talk() が呼び出されるように指定してみる】で
class D(B, C): def talk(self): super(C, self).talk() # C を明示する def main(): d = D() d.talk()
の結果は
This is A.
となったが、これは C.talk() を探したわけではないみたい。
super オブジェクトの意味は、
指定クラスの親クラスを指す
らしく、
super(C, self).talk() は (C の親 = A).talk() を呼び出す。
と動いた。
というのも、
class C(A): def talk(self): print 'This is C.'
としたとき、
This is A.
を返してきたから。
ダイヤモンド継承をしたときの super() の使い方がようわからん。
という訳で、フリダシに戻る。
class D(B, C): def talk(self): C.talk(self)
とすればいいのは、分かってんだけどね。