python_sqlite3_commit
Pythonにはsqlite3という、SQLiteのインターフェイスモジュールがあるんだけど、Python 2.5の日本語ドキュメントのとおりやろうとすると微妙にハマる、という話。
日本語ドキュメントのsqlite3ページには、以下のようなコード例が載ってます。
c = conn.cursor()
# Create table
c.execute('''create table stocks
(date text, trans text, symbol text,
qty real, price real)''')
# Insert a row of data
c.execute("""insert into stocks
values ('2006-01-05','BUY','RHAT',100,35.14)""")
ところが、これだと実際にはinsertがデータベースに反映されない。実はinsertなどの操作を行った最後に、sqlite3.Connectionオブジェクトのcommit()メソッドを行わないとコミットが行われず、変更が実行されない模様。
で、実はPython 2.5.2ドキュメントのsqlite3ページには、このあとに以下のようなコードが追加されております。
# Save (commit) the changes conn.commit() # We can also close the cursor if we are done with it c.close()
にも関わらず、「Connection Object」のページにはcommit()に関する記述がないのでさらに混乱は深まる……。ちなみに、Python 2.6.4のドキュメントではちゃんとcommit()メソッドについて記述されており、commit()を実行しないとデータベースへの変更が行われないよ、またrollback()メソッドを実行すれば前回のcommit()までの内容を取り消せるよ、との旨が書かれてます。
教訓:日本語ドキュメントを当てにせず、ちゃんと原文を読め。
Pythonネタ:クラスメソッドを動的に生成する
Pythonには動的に関数を作ったり、クラスのメソッド呼び出しをカスタマイズするための機構が用意されています。ということで、それを使って遊んでみた。
まず、Pythonではクラスで__getattr__メソッドを定義することで、クラスに対する任意の属性値アクセスを横取りすることができる。
Pythonのクラスやオブジェクトは、それぞれが持つ属性(クラスならメンバ関数/変数)を__dict__というdictionary内に格納している。たとえばとあるオブジェクトaに対し「a.x」という操作を行うと、まずPython処理系はそのオブジェクトが持つ__dict__内で「x」という名前を持つメンバ変数/関数を探し、存在しなければ続いてそのオブジェクトのクラスが持つ__dict__内、続いてそのクラスの派生元クラスの__dict__内、という順でメンバ変数/関数を探索する。
この作業を行って、通常すべての__dict__内で該当する名前が存在しなければエラーとなり例外を発生させるのだが、もしオブジェクト/クラス/派生元クラス内で__getattr__()メソッドが定義されていた場合、例外を発生させずに__getattr__()メソッドが呼び出される仕組みになっている。
まぁ、サンプルコードを見たほうが分かりやすいかと。下記は、メソッドを呼び出すと、そのメソッド名を返すというクラス「echo」の例。
$ python Python 2.6.1 (r261:67515, Jul 7 2009, 23:51:51) [GCC 4.2.1 (Apple Inc. build 5646)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> class echo(object): ... def __getattr__(self, name): ... return lambda: name ... >>> o = echo() >>> o.hoge() 'hoge' >>> o.foobar() 'foobar' >>> o.abcdefg() 'abcdefg'
__getattr__()メソッドは、あるオブジェクトの属性値/属性メソッドにアクセスしようとした際に、そのオブジェクト/クラス/派生元クラス内で目的となる属性が見つからなかった場合に呼び出される。引数nameにはアクセスしようとした属性の名前が与えられる。ここではlambda構文を使用し、引数nameを返す関数を__getattr__の戻り値とした。
また、オブジェクトの__dict__属性に値を追加することで、動的に任意の属性をオブジェクトに追加できる。
下記は、オブジェクトにメソッドを追加するメソッド「teach」を備えたクラス「echo2」の例。
>>> class echo2(object):
... def teach(self, key, value):
... self.__dict__[key] = lambda : value
...
>>> o = echo2()
>>> o.hoge()
Traceback (most recent call last):
File "", line 1, in
AttributeError: 'echo2' object has no attribute 'hoge'
>>> o.teach("hoge", "foobar")
>>> o.hoge()
'foobar'
>>> o.teach("abcdefg", "alphabet")
>>> o.abcdefg()
'alphabet'
このへんの仕組みがどのような場合に有効化というと、たとえば単純なメソッドを大量に用意したい場合。下記は、「False」を返すis_a()〜is_z()までを一気に定義するというもの。
>>> for i in "abcdefghijklmnopqrstuvwxyz": ... o.__dict__["is_"+i] = lambda : False ... >>> o.is_a() False
覚えておくと、たまにラクができるかも。
整備済み製品iMacを買ったレポート
先日、新しいiMacが発売されましたがそこからさかのぼること約2週間前、実は自分はiMacを購入していたのでした。新iMacはフルモデルチェンジに近いアップデートだったのでそこそこ残念な気分ではあったんだけど、実は整備済み製品を購入したためにかなりお得だったので、そこまでのショックはなかったり。

我が家のiMac
整備済み製品というのはオンラインのApple Storeで販売されているもので、初期不良などで返品されてきたMacやiPodをAppleが修理・点検、「新品水準並の品質」を確認したうえで販売するというもの。パッケージが開封済みだったり、品質には問題ないレベルの傷があったりする場合があるんだけど、基本的には新品同様の品。ただ、完全な新品ではないのでその分定価より1〜2万円程度安いのが特徴です。さらに、BTOでカスタマイズされていたものも混ざっている(しかも価格はそのまま)ので、運が良ければ通常よりも高いスペックのものが手に入る可能性もあったりします。
で、自分が買ったのは2009年3月発表モデルの、20インチiMac。ちなみに定価は標準モデルで12万8,800円ですが、整備済み新品ということでお値段は10万9,800円。約2万円近く安くなってました。しかも標準モデルはメモリが2GB、HDDが320GBなのですが、届いたiMacにはメモリが4GB、HDDが640GBにカスタマイズ済み。ちなみに現行の(自分が買った約2週間後に発売された)iMac 21.5インチモデルは11万8,800円なので、まぁ納得できる感じです。

整備済み製品iMacの購入明細
ただ、地味に残念だったのが、Mac OS X 10.6 Snow Leopardが発売されたあとだったのに、同梱されているのが10.5 Leopardだった点。しょうがないので届いたその日のうちにSnow LeopardのUp-To-Date版(980円)を注文する必要があったのが面倒くさかった……。
整備済みiMac、開封レポート
ということで我が家に届いたiMacですが、整備済み製品はパッケージが通常と違う模様で、おなじみの製品写真付きパッケージではなく、白箱に入って届きました。箱には「整備済み製品特別販売用保証書」付き。

パッケージは無地の白箱
箱の外側は違ったけど、中身は基本的には通常と同じ。キーボードやマウス、DVDなどの周辺機器は小箱に入ってる点も同じ。それぞれ開封されたあとはあったけど、特に目立つ汚れは無し。

中身は通常の製品と同じ

付属品も開封の跡がありました
マウスはMighty Mouse、キーボードはワイヤードのテンキー付きモデル。新iMacではワイヤレスキーボード+Magic Mouseなので、そこだけは残念なところ。ちなみにキーボードのテンキー横にスジ状の傷はあったけど、特に問題はない感じ。てか、机が狭かったので速攻でテンキーなしキーボードを買ってしまったり。

キーボードのテンキー脇に若干の傷を発見
本体を覆う保護シートも開封されてはいたけど、本体に傷・汚れはなし。OSも問題なく起動しました。すぐにSnow Leopardを入れてしまいましたが……。

保護シートにも開封跡あり
ということで、買ってから2週間後に新モデルは出てしまいましたがこのiMac、スペック的にはまったく不便はなし。以前はMacBookの再下位モデルを使っていて、CPUのクロック数的には若干向上したくらいなのに体感的には相当変わっていてビックリです。新品で旧iMacを買っていたら新モデルの発売で多分相当にダメージを受けていたとは思いますが、安かったのでまぁ許せるところ。皆様もMacの新モデル発表の噂があるにも関わらずMacが欲しくてたまらなくなった場合は、整備済み製品を狙ってみるといいんじゃないでしょうか。
ちなみに、浮いたお金は1TBのFireWire接続HDDとFireworkdsのアップデートに消えました……。HDDの容量がでかいと、バックアップ用HDDの容量も必要なので大変です。
木の自転車
WordPressの記事編集画面を改善する
Wordpressを導入して困ったのが、記事編集時に勝手に整形されるところ。たとえば、段落の頭の全角アキ(全角スペースね)が勝手に削除されたり、画像を貼りたいときに<div></div>で囲っても勝手にタグが削除されちゃったり。
めちゃくちゃ不満だったので、設定とかで改善できないか、(極端な話、HTMLでのコーディングに慣れているのでビジュアルエディタなんかなくてもOKなので)エディタをシンプルなものにできないかを調べたところ、どうやら「PS Disable Auto Formatting」なるプラグインを導入すれば解決すると判明。
ということでさっそく入れてみたところ、HTMLエディタでの使えねー整形は見事に無効化されました?(^o^)/。これで段落頭の全角アキも入れられます! ただ、ビジュアルエディタとHTMLを切り替えると段落頭の全角アキがカットされる問題はまだあったりするわけですが、とりあえず問題点は解決。あと、ビジュアルモードで保存してもやっぱりカットされちゃう。ビジュアルエディタは使うな、ってことですね;-)
あとは、夜間帯に重い問題が解決すれば万事OKなんだけど、こればっかりはなかなか難しそう。
