Edited at

pathlibで複数の拡張子を許容してファイルを取得/削除する

More than 1 year has passed since last update.


はじめに

久々の投稿です. 今回は自分がたまに疑問に思う「該当する拡張子だけ取得する方法」について, 自分の考えた方法を載せてたくさん厳しい意見を聞けたらいいなと思いつつ書きます.

背景としては, CNNやFCNなどの画像に関するDeepLearningの技術に取り組んでる際, Augmentationなどで画像ファイルを取得して画像を変化させたいので, 画像だけ確実に取得していたいと思うわけです. そこで普通ならos.listdirとか使って取得するんですが, せっかくpathlibが登場してるのにその時だけそっちに乗り換えるのはアレな気がしたので, とりあえず実装してみました.


縛り


  • 拡張子が以下であるファイル全てを取得/削除


    • jpg

    • png

    • bmp



  • import可能なのはpathlibのみ


取得

リスト内包表記で書くこと自体は良いんですが, 下のような実装になってもどかしい思いをしていました.

何よりもpathlibのglob内で正規表現使えないのがしんどいです.(osの場合もそうかもしれませんが)


最初にやってた実装

見ればわかる通り長いですよね. 可読性は百歩譲ってあったとしても, 同じ処理を何度もやって足し算してるの良くないなあと思ってはいたんですが, しばらく良い方法が思いつきませんでした.

path = Path('hoge/huga/')

img_files = list(path.glob('*.jpg')) + list(path.glob('*.png')) + list(path.glob('*.bmp'))


思いついた実装

思いついたというか, pathlibには拡張子を表示してくれるsuffixメソッドがあるので, それを利用して実装しました.

他にもstemだったりnameだったり, 何か工夫して取得したい時には便利なものがいくつかあるので, 場合に応じて調べて使ってみると良いと思います.

exts = ['.jpg', '.png', '.bmp']

img_files = [img for img in path.glob('*') if img.suffix in exts]


削除

これ以上のものが思いつかなかったんで我こそはって方お待ちしています.

unlinkって名前だとシンボリックリンクだけ解除しそうなんですが, ちゃんとファイルごと削除してるみたいです

path = Path('/hoge/huga/')

exts = ['.jpg', '.png', '.bmp']
for target in path.glob('*'):
if target.suffix in exts:
target.unlink()


追記(2018/10/26)

コメントしてくださった実装方法がスマートな気がします。

自分でももう少し考えてみます。