Posted at

Paver を使ったスクリプティング - ファイル操作編

More than 5 years have passed since last update.

Python の標準ライブラリのファイル操作、 os にあるのか os.path にあるのか、 shutil にあるのかで悩むことないですか?

paver.path モジュールにある path クラスを使うと、ファイル操作が Python の標準ライブラリよりも簡単になります。


使い方

path クラスも paver.easy に入っているので、 from paver.easy import * してあると path だけで利用できます。

この path クラスは文字列を継承して、その文字列を引数に取るような操作をするメソッドを定義しています。また / 演算子にパスの結合操作をオーバーライドしていたり、その他さまざまな便利メソッドを定義してあります。

>>> from paver.easy import *

>>> root = path('/')
>>> root
path(u'/')
>>> root.isdir()
True
>>> root.listdir()
[path(u'/.dbfseventsd'), path(u'/.DocumentRevisions-V100'), path(u'/.DS_Store'), path(u'/.file'), path(u'/.fseventsd'), path(u'/.Spotlight-V100'), path(u'/.SymAVx86QSFile'), path(u'/.Trashes'), path(u'/.vol'), path(u'/Applications'), path(u'/asix_temp'), path(u'/bin'), path(u'/cores'), path(u'/dev'), path(u'/etc'), path(u'/home'), path(u'/Library'), path(u'/mach_kernel'), path(u'/net'), path(u'/Network'), path(u'/opt'), path(u'/private'), path(u'/sbin'), path(u'/System'), path(u'/tmp'), path(u'/Users'), path(u'/usr'), path(u'/var'), path(u'/Volumes'), path(u'/\u30e6\u30fc\u30b5\u3099\u60c5\u5831')]
>>> root / 'usr'
path(u'/usr')

os, os.path, shutil にあるパス操作以外の便利メソッドには、パスで指定されたファイル内のバイト列を読み込んで返す .bytes() メソッドや、 glob() メソッド、 .remove() と違ってファイルが存在しなくてもエラーにならない .remove_p() メソッドなどがあります。


dryrun

paver コマンドは -n オプションを指定すると dryrun モードになっており、 path クラスの操作メソッドは実際には何もしなくなります。


pavement.py

from paver.easy import *

@task
def hello():
path('/').rmtree()


$ paver -n hello

---> pavement.hello
rmtree / () {}


pushd

これはもともと Python の contextlib にある機能なのですが、 with 文と組み合わせて使うと便利な pushd というコンテキストマネージャがあり、 paver.easy に入っているのですぐに使えます。


pavement.py

from paver.easy import *

import os

@task
def chdir():
print "cwd: ", os.getcwd()
with pushd('/'):
print "cwd: ", os.getcwd()
print "cwd: ", os.getcwd()


$ paver chdir

---> pavement.chdir
cwd: /Users/inada-n/paver
cd /
cwd: /
cd /Users/inada-n/paver
cwd: /Users/inada-n/paver