傀儡師の館.Python
2026
2025
2024
2023
2022
2021
2020
2019
2018
2017
2016
2015
2014
2013
2012
2011
2010
2009
2008
2007
2006
2005
2004
2003
2002
1月
2月
3月
4月
5月
6月
7月
8月
9月
10月
11月
12月
全1件 (1件中 1-1件目)
1
以前、Python のファイル参照や操作は面倒だというあなたに path モジュール という記事を書いた。標準ライブラリの os.path はイマイチ使いにくい。Python を使ってディレクトリやファイルをたどりながら何かするのは面倒。たとえば、このディレクトリの下のファイル名が「~」で終わっているファイルを削除したいとかいうのを書こうとすると、unix だったら find コマンドを使って、find . -name \*~ -print -exec rm {} \; とかあるわけで、そんな風にもっと簡単にできないかなぁと思う人も多いだろう。で、path モジュールを使えば、この手のものも簡単に書けるようになる。path だと、import pathd = '/var/apache/htdocs'for f in d.walkfiles('*~'): f.removeのような書き方ができた。ちなみに、os.path (python 2) を見ると os.path.walk があるが os.path (python 3) にはない。os.walk が残っている。python 3 では、pathlib — オブジェクト指向のファイルシステムパス が追加されているが、やっぱりもっと直感的に使えるようなものが欲しい。そこで、pyfs の登場となる。"pip install pyfs" でインストール。import fstarget_path = /var/apache/htdocs# 一ファイルずつ削除for f in fs.find('*~', target_path): fs.rm(f)# あるいは、まとめて削除to_delete = fs.find('*~', target_path)fs.rmfiles( to_delete )path や pathlib のようにファイルパスをオブジェクトとして、それを使って操作するという感じではなく、直接的に UNIX のコマンドのような感じで操作できる。ということで、気に入ってしまった。ソースを見てみればわかるが、かなりの部分が os.path や os をラップしているだけなので、基本を覚えるのは簡単。fs.exists(path) : os.path.exists(path)fs.isfile(path) : os.path.isfile(path)fs.rename(oldPath, NewPath, **kwargs) : os.rename(oldPath, newPath, **kwargs)fs.chdir(path, **kwargs) : os.chdir(path, **kwargs)fs.stat(path) : os.stat(path)fs.ctime(path) : os.stat(path).st_ctimefs.atime(path) : os.stat(path).st_atimefs.mtime(path) : os.stat(path).st_mtimefs.abspath(path, **kwargs) : os.path.abspath(path, **kwargs)fs.normalize(path, **kwargs) : os.path.normpath(path, **kwargs)fs.rm(path, **kwargs) : os.unlink(path, **kwargs)fs.unlink(*args, **kwargs) : os.unlink(path, **kwargs)fs.rmdir(path, recursive=True, **kwargs) : shutil.rmtree(path, **kwargs)fs.rmfiles(paths, **kwargs) : os.unlink(path, **kwargs)fs.exists(path, **kwargs) : os.path.exists(path, **kwargs)fs.cwd() : os.getcwd()fs.basename(path, ext="") : os.path.basename(path).replace(ext, "")fs.dirname(path) : os.path.dirname(path)fs.sep : os.path.sepこれらに加えて、fs.truncate(path, **kwargs) : path 以下のすべてのファイルとディレクトリを削除fs.rmdir(path, recursive=True, **kwargs) : path のディレクトリを削除 (再帰的に削除は、recursive=True を指定。 os.rmdir か os.rmtree で削除している)fs.rmfiles(paths, **kwargs) : リストで渡されたファイルを削除fs.rmdirs(paths, **kwargs) : リストで渡されたディレクトリを削除fs.mkdir(path, recursive=True, **kwargs) : Unix コマンドの mkdir と同じ。 recursive=True で、mkdirsfs.touch(path) : Unix のタッチコマンドと同じ。fs.list(path='.') : os.listdir(path) の結果を isfile してファイルだけ残して、 iterable にしている。fs.listdirs(path='.') : os.listdir(path) の結果を isdir してディレクトリだけ残して iterable にしている。fs.find(pattern, path='.', exclude=None, recursive=True) : パターンに指定されたファイルを iterable に返す。 exclude で除外ディレクトリも指定できる。再帰的適応も可。 os.walk で走査して、fnmatch.filter でフィルタしている。fs.finddirs(pattern, path='.', exclude=None, recursive=True) : find のディレクトリ版。fs.join(*args, **kwargs) : os.path.join(*args, **kwargs) と同じ。 +リストで引数を渡すことができる。fs.extname(path, **kwargs) : name, ext = os.path.splitext(path, **kwargs) の ext を返す。fs.open(path, mode='r', **kwargs) : 標準の open(path, mode, **kwargs)fs.write(path, content, encoding="UTF-8", append=False, raw=False) : 標準の open を使って エンコード指定で書き込む。fs.read(path, encoding="UTF-8") : 標準の open を使って、エンコード指定で読み込む。fs.append(*args, **kwargs) : fs.write(*args, append=True, **kwargs)fs.get(*args, **kwargs) : fs.read(*args, **kwargs)fs.put(*args, **kwargs) : fs.write(*args, **kwargs)fs.filename(*args, **kwargs) : fs.basename(*args, **kwargs)fs.extension(*args, **kwargs) : fs.extname(*args, **kwargs)要するに、a pythonic file system wrapper for humansAn easy to use file system wrapper for Python that aims to simplify os, os.path, os.walk, shutils, fnmatch, etcということ。サンプルを少し見てみる。*.xls か、*.xlsx を探してきて何かしたい。for filename in fs.find(['*.xls', '*.xlsx']): passconfig ディレクトリにある *.ini ファイルを local_* 以外取り出して何かしたい。for filename in fs.find('*.ini', path='config', exclude='local_*'): passVagrantfile を config ディレクトリから探して何かしたい。見つからなければ None。filename = next( fs.find('Vagrantfile', path='config'), None)backup ディレクトリにある *.sql のうち最新のアクセス時刻があるファイルを取り出して何かしたい。filename = max( fs.find('*.sql', path='backup'), key=fs.ctime).git ディレクトリを見つけて削除したい。for dir in fs.finddirs('.git'): fs.truncate(dir)なくても困らないけど、あれば、便利で、書くコードが短くて済むし、可読性もよくなるので、ちょっとツールを作るときに重宝すると思う。
2015.04.12
コメント(0)