ASPN : Python Cookbook : subscriptable generator

内部キャッシュを使っていてリストのようにアクセスできるジェネレータ、とのこと。
ジェネレータって関数のジェネレータとは違うよね。
キャッシュにはSQLObjectを使っていて富豪的な感じ。PickleColにオブジェクトをそのまんまつっこんでいる。

三項演算子を使ってるところがあるので、そのままだとPython2.4では実行できない。

return [self._getFromCache(i) for i in xrange(k.start, k.stop, 1 if k.start < k.stop else -1)]

わかりにくいけどxrangeの第三引数が、k.start < k.stopなら1、そうでなければ-1。

調べたこと

  • tempfileモジュール
  • 反復処理できるクラスのイディオム
  • __iter__()/next()
  • __getitem__(self, key)/__setitem__(self, key, value)

tempfileモジュール

一時ファイルを作るときに使う。TemporaryFileでオブジェクトを返させる方法とmkstempでパスを取る方法がある。

TemporaryFile() と違って、mkstemp() で生成されたファイルが用済みになったときにファイルを消去するのはユーザの責任です。

とリファレンスに書いてある。なのでこのレシピだと実行するたびに/tmp/の下にファイルが増えていく。

反復処理できるクラスのイディオム

forループとかinでのチェックでは反復処理の前にまず__iter__が呼ばれる。(『初めてのPython』p.401)
__iter__で取得したイテレータのnextが繰り返し実行される。StopIteration例外が起こると終了。
__iter__がない場合は__getitem__がIndexErrorが起こるまで呼ばれる。
つまりどちらかが実装されていればそのクラスのインスタンスはforループなどに使えるようになる。

__iter__()/next()

両方を実装したものがイテレータと呼ばれる。

__getitem__(self, key)/__setitem__(self, key, value)

__getitem__はobject[1]とかobject[1:10]を使えるようにする。
前者だと__getitem__は整数値を受け取り、後者だとスライスオブジェクトを受け取る。
スライスオブジェクトというのは単に開始値と終了値とステップ値を持つもので、それらの値にはstart、stop、step属性でアクセスできる。
__setitem__は整数値だけを取る。