コンテキストマネージャーを使う

前回の続きです。コンテキストマネージャーを使うと、さらに記述がすっきりするようなので、早速試してみました。まずは、Partitionクラスをコンテキストマネージャーにします。クラスをコンテキストマネージャーにするには、特殊関数__enter__と__exit__を定義します。

class Partition():
    def __enter__(self):
        self.mount()
        return self


    def __exit__(self, exc_type, exc_value, traceback):
        self.umount()
        if exc_type:
            return False
        return True

次に、do_backup関数をwithステートメントを使って書きかえます。

def do_backup(partition, dest_mtpt):

    with Partition(partition) as part:
        exec_command('rsync', [part.get_mtpt() + '/', dest_mtpt])

# def do_backup():

こうすると、withステートメントでクラスオブジェックトが生成された後、__enter__メソッドが呼ばれます。その後、制御はブロックに移り、exec_command関数が実行されます。そして、ブロックの実行が終了した後で、__exit__メソッドが実行されます。この例では、rsync実行前にpart.mount()メソッドが実行され、ブロック終了後にpart.umount()メソッドが呼ばれることになります。あの、長ったらしかったdo_backup関数が、たったの2行になってしまいました。

すごく便利な機能だと思います。さらに詳しい解説はコチラ