dircache – ディレクトリの内容をキャッシュする

目的:ディレクトリの内容をキャッシュして、そのディレクトリの変更時に更新する
利用できるバージョン:1.4 以上

ディレクトリの内容を表示する

dircache モジュール API の 主な関数は、 os.listdir() のラッパーである listdir() です。それは名前を持つディレクトリの更新時刻が変更されない限り、渡されたパスで呼び出される度にその結果をキャッシュして同じ list を返します。

import dircache

path = '.'
first = dircache.listdir(path)
second = dircache.listdir(path)

print 'Contents :', first
print 'Identical:', first is second
print 'Equal    :', first == second

毎回、厳密に同じ list が返されるので、その対象ディレクトリが変更されていないことを認識するのが重要です。

$ python dircache_listdir.py
Contents : ['__init__.py', 'dircache_annotate.py', 'dircache_listdir.py', 'dircache_listdir_file_added.py', 'dircache_reset.py', 'index.rst']
Identical: True
Equal    : True

ディレクトリのコンテンツが変更される場合、再スキャンされます。

import dircache
import os

path = '/tmp'
file_to_create = os.path.join(path, 'pymotw_tmp.txt')

# ディレクトリのコンテンツを調べる
first = dircache.listdir(path)

# 新しいファイルを作成する
open(file_to_create, 'wt').close()

# ディレクトリを再スキャンする
second = dircache.listdir(path)

# 作成したファイルを削除する
os.unlink(file_to_create)

print 'Identical :', first is second
print 'Equal     :', first == second
print 'Difference:', list(set(second) - set(first))

このケースでは list に新しいファイルが作成されます。

$ python dircache_listdir_file_added.py
Identical : False
Equal     : False
Difference: ['pymotw_tmp.txt']

それぞれのパスを再チェックするためにそのコンテンツを破棄して、完全にキャッシュをリセットすることもできます。

import dircache

path = '/tmp'
first = dircache.listdir(path)
dircache.reset()
second = dircache.listdir(path)

print 'Identical :', first is second
print 'Equal     :', first == second
print 'Difference:', list(set(second) - set(first))

リセットされた後で新たな list インスタンスが返されます。

$ python dircache_reset.py
Identical : False
Equal     : True
Difference: []

自動的な表示

dircache モジュールで提供されるその他の興味深い関数は annotate() です。 annotate() が呼び出されると、 listdir() が返すようにディレクトリ名の最後に '/' を追加して list() を変更します。

import dircache
from pprint import pprint
import os

path = '../..'

contents = dircache.listdir(path)

annotated = contents[:]
dircache.annotate(path, annotated)

fmt = '%25s\t%25s'

print fmt % ('ORIGINAL', 'ANNOTATED')
print fmt % (('-' * 25,)*2)

for o, a in zip(contents, annotated):
    print fmt % (o, a)

Windows ユーザには不幸なことに、 annotate() が調べる名前を作るために os.path.join() を使用しますが、 os.sep ではなく必ず '/' を追加します。

$ python dircache_annotate.py
                 ORIGINAL                       ANNOTATED
-------------------------       -------------------------
                      .hg                            .hg/
                 .hgcheck                       .hgcheck/
                .hgignore                       .hgignore
                  .hgtags                         .hgtags
              LICENSE.txt                     LICENSE.txt
              MANIFEST.in                     MANIFEST.in
                   PyMOTW                         PyMOTW/
               README.txt                      README.txt
                      bin                            bin/
                   module                          module
                     motw                            motw
              pavement.py                     pavement.py
             pavement.py~                    pavement.py~
                  refresh                         refresh
   sitemap_gen_config.xml          sitemap_gen_config.xml
                   sphinx                         sphinx/
                trace.txt                       trace.txt
                    utils                          utils/
                      web                            web/

See also

dircache
本モジュールの標準ライブラリドキュメント
Bookmark and Share