decorator

コロナ禍でいろんな勉強が捗るって話もあり、pythonのdecoratorを復習してました。
ちょっと取っつきにくいテーマではあるのですが、関数(def ... というやつ)に機能を付け加えるやつ、みたいに覚えておけばいいんじゃないですかね(雑すぎるか、、)

行ったり来たりと、EDAする時に使えるかも

と思ったのです。探索的なデータ解析(Exploratory Data Analysis)時って、どんだけ時間がかかるか、って忘れがちなのでdecoratorで予め用意しとけば、毎度毎度処理計測時間を書かなくて多少は楽かなー、と。

例えば、こんな処理をしてる1として

1
2
3
def counts(n):
## 単純に、数を数えてるだけだし、ある意味`n`が出力されるだけです。。
return sum([1 for i in range(n)])

処理時間を計算したくなったとする、と。安直にやれば、

1
2
3
4
5
6
7
8
9
10
11
import datetime

## 処理開始に時刻取っておいて
start = datetime.datetime.now()

### ココに処理を入れる、、、

## 何分かかったかな?を、差分で取る
timelapse = datetime.datetime.now() - start

print(timelapse)

なんてことをやってたのですが、前処理(start = ...)と後処理(timelapse..print(..))を出力しちゃえばいいや、と。

ということで、こんなお手製のdecorator作ってみました、と。

1
2
3
4
5
6
7
8
def time_lapse(func):
def wrapper(*args, **kwargs):
start = datetime.datetime.now()
result = func(*args, **kwargs)
timelapse = datetime.datetime.now() - start
print(timelapse)
return result
return wrapper

で、作った後に、元の関数を@を付けてデコレートしてあげればいい、と。

1
2
3
4
5
6
7
@time_lapse
def counts(n):
return sum([1 for i in range(n)])

## 実行すると、こんな感じ:
## 0:00:07.803982
## 100000000

実際使おうとすると

100万件を一気に!というのも男気溢れる感じなので、まずは100件、1000件とデータ数を増やしていって、処理時間の推移を横目で見ながら最後に全件、、とかな気もしますが。

References:

+ [Next Step Python: Decorator](https://www.linkedin.com/learning-login/share?forceAccount=false&redirect=https%3A%2F%2Fwww.linkedin.com%2Flearning%2Fnext-step-python-decorators%3Ftrk%3Dshare_ent_url&account=3322): 関数の関数、て話から、decoratorの使い方、HTMLにタグを入れるってのをdecoratorで実装してみたり、最後はFlaskで使うdecoratorまで書いてあります。

1 普通、もっと難しいことをやると思いますけどね、普通は。