Pythonでしょ!

Pythonでいろいろやってみましょう! ビッグデータ、画像処理、WebSiteなどなど

Pythonのクロージャ


クロージャとは

wikipedia:クロージャにご参考

クロージャを使ってどんな便利なことができるでしょうか?

クロージャの用途
・ライブラリの設計者はクロージャを関数への引数として渡すことで利用者が挙動をカスタマイズ可能なようにできる。
例えばソートを行う関数は比較のコードをクロージャとして引数にとることで利用者が定義した基準でソートできるようになる。
wikipedia:クロージャより引用

データのソートを例にしましょう
ソートのFunctionは簡単に作れると思います
例えば書きバブルソートを作りました、

def bubble_sort(data):
    #Bubble sort必要なPASS
    for p in range(len(data)-1, 0, -1):
        #アイテム位置交換
        for idx in range(p):
            if  data[idx] > data[idx+1]:
                temp = data[idx]
                data[idx] = data[idx+1]
                data[idx+1] = temp


[3,1,4,2]の整数のリストが入力されたら、
昇順のリスト[1,2,3,4]が出力されます。
では、
降順にしたい場合とか
どう簡単に実現できるのでしょうか

クロージャの出番です

比較する部分

            if  data[idx] > data[idx+1]:

を動的に変更できれば
必要な結果が出るのではないでしょうか

下記のサンプルをみましょう

#!/usr/bin/env python
# -*- coding: utf-8 -*-

#ユーザ定義comparator(昇順)
def cmp_asc(x,y):
    if x > y:
        return True
    else:
        return False

#ユーザ定義comparator(降順)
def cmp_desc(x,y):
    if x < y:
        return True
    else:
        return False

def bubble_sorter(comparator):
    def sorter(data):
        #Bubble sort必要なPASS
        for p in range(len(data)-1, 0, -1):
            #アイテム位置交換
            for idx in range(p):
                #ユーザ定義comparatorを使って位置交換の条件
                #昇順、降順など順位のコントロールは可能になる
                if comparator(data[idx], data[idx+1]):
                    temp = data[idx]
                    data[idx] = data[idx+1]
                    data[idx+1] = temp
    return sorter

if __name__ == "__main__":
    #昇順
    sort = bubble_sorter(cmp_asc)
    data = [3,1,4,2]
    print u"昇順:"
    sort(data)
    print data

    #降順
    sort = bubble_sorter(cmp_desc)
    data = [3,1,4,2]
    print u"降順:"
    sort(data)
    print data

*1
*2

上のソースのマジックを考えましょう
1) bubble_sorterは直接ソートするではなく、sorter関数を返す
2) sort(data)実行する時 bubble_sorterの引数comparatorを使う

この事例はここまで
次回は別のサンプルを作ります

*1:上のソースコードはPython2.7(Linux)テスト済み

*2:他の実装方法もあります、あくまでクロージャを利用する例です