5分でPythonは便利と思えるレシピ

January 01, 2011 at 05:58 PM | View Comments

@nishioが嘆いていたので5分でpythonが便利と分かると思われるスクリプトを書いてみました。

Pythonで5分で便利なことをするレシピ - 西尾泰和のはてなダイアリー

5分で便利と言っても対象が誰かによって違うと思うのですが、元ネタがPHPプログラマ対象のようでしたので、PHPプログラマやプログラムを普段書かない人向けです。

元ネタはPHPっぽくPythonを使っていましたが、今回はバッチプログラム風です。Webアプリを作る上でPHPは便利だと思うのですが、ファイル操作したり集計したりするときにPHPは向いていないと思います。PHPプログラマの人は普段なにを使っているのでしょうか??

5分でわかる Python を知らない人が Python の便利さを学べる記事をかいたよ | HIROKI.JP

プログラムをやってみたい!と言う人はだいたいPHPから入るみたいですが、

  • apacheなどのWebサーバーの管理もするのか?
  • 作ったWebアプリを公開するのか?セキュリティ大丈夫??
  • phpはWeb以外のことをやろうとすると激しく面倒

ということからも初心者用プログラム = PHP というのに疑問を感じます。Webアプリを公開するってハードルがとてつもなく高くないですか??

そんなわけで、PHPオンリープログラマやプログラムを始める人はWebアプリより、普段の手でやると面倒な仕事を自動化できるようなプログラムを書けるようになるといいと思います。

linuxやマックなら、シェルやperlなどいろいろあるのでPythonで無くてもいいと思いますが、PythonはWindowsでも簡単にインストールできて完全に動くので便利、オススメです。

今回は良く使うファイル操作のバッチプログラムを書いてみました。

元ディレクトリを再帰的に探して、特定の拡張子のファイルをコピー先ディレクトリにコピーするプログラムです。

Pythonのファイル操作はいろいろあるのですが、os.walkは再帰的にディレクトリを渡り歩く関数で非常に便利です。Pythonを使い始めの頃からずっと愛用しています。

16.1. os ? 雑多なオペレーティングシステムインタフェース ? Python v2.6.2 documentation

今回作ったプログラムは

% python filecopy.py 元ディレクトリ コピー先ディレクトリ 拡張子

という使い方をします。

#! /usr/bin/env python
# vim: fileencoding=utf8

import os
import sys
import shutil
import logging as logger

def copyfile(path, to_path, ext):
    """
    pathの中の全ての拡張子がextのファイルを
    to_pathにコピー
    """
    logger.debug("args path %s to_path %s ext %s " % (path, to_path, ext))
    # os.walk で path内のディレクトリを全部なめる
    # ディレクトリのなかにディレクトリがあっても一つ一つ取得してくれる
    for root, dirs, flist in os.walk(path):
        # flistはファイルの配列なので一つ一つ処理
        for fname in flist:
            logger.debug("root:%s fname:%s" % (root, fname))
            # hoge.JPG のようなファイル名から拡張子を取得
            # 大文字は小文字にする
            # ex)
            # os.path.splitext(fname) で ("hoge", ".JPG") に分解
            # [-1] で .JPG  (上の要素の一番最後を取得
            # .lower() で .jpg ( すべて小文字に変換
            # [1:] で jpg (2番目の文字から最後までを取得
            file_ext = os.path.splitext(fname)[-1].lower()[1:]
            logger.debug("file ext %s " % file_ext)
            # 拡張子が一致したら処理
            if ext.lower() == file_ext:
                # root(c:\temp\hogeのような親ディレクトリ)とhoge.JPG を 合体させる
                filepath = os.path.join(root, fname)
                # to_pathにコピー
                shutil.copy2(filepath, to_path)
                logger.info("copy %s to %s" % (filepath, to_path))


# if __name__ == "main": でバッチとして実行できる
if __name__ == "__main__":
    # sys.argv には 実行ファイル名 オプション ,,,, のリストが入っている
    if len(sys.argv) < 3:
        print r"usage copyfile.py c:\temp\hoge c:\temp\huga jpg"
        sys.exit()
    path = sys.argv[1]
    to_path = sys.argv[2]
    ext = sys.argv[3]
    copyfile(path, to_path, ext)

今回は拡張子でファイルを選択しましたが、慣れてきたら

  • 正規表現のパターンを渡す
  • ファイルを返すgenerator関数と処理をする関数を分ける

などすると面白いと思います。

categories: python
blog comments powered by Disqus
track feed ueblog