18
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Python】@ってなんぞ?(デコレータについて)

Last updated at Posted at 2014-02-13

pyramidのチュートリアルを進めてるんだけど、知らないことがたくさん出てくる。

とりあえず、しょっぱなに@のついたソースが出てきた。
Java使ってると、どうしてもアノテーションかと思ってしまうわけだけど、
そんなわけもなく、調べてみると、デコレータだそうです。

デコレータっていうのは、オブジェクトをラップするために使用するもの。
デザインパターンにあったね、そんなの。

んで、Pythonではそのデコレータが機能として提供されているみたい。
デコレータを使用した簡単なソースを書いてみた。


# デコレータ(デコレートする関数の前に"before"、後ろに"after"を出力する)
def deco_test(func):
    def wrapper(arg):
        print("before")
        func(arg)
        print("after")
    return wrapper


# デコレータを使用した関数@を使ってデコレータを呼び出す。
@deco_test
def hello(arg):
    print("Hello, " + arg)

hello("world!")

実行結果は下のようになる。
before
Hello, world!
after

ちなみに、デコレータを使用したhello関数は下の関数に置き換えることができる

def hello(arg):
    print("Hello, " + arg)
hello = deco_test(hello)

最初はよくわからなかったけど、いろいろ試してみて、
Pythonは関数もオブジェクトってのを強烈に覚えた。
関数が引数になっている。それで、関数を格納した変数に()をつけて実行すると。

すごく柔軟にプログラム書けそうだけど、
動的型付けだし、命名しっかりやらないと、
とっても分かりづらいコードが出来上がりそう。

ちなみに、pyramidのチュートリアルで出てきたコードは以下の通り

@view_config(route_name='home', renderer='templates/mytemplate.pt')
def my_view(request):
    try:
        one = DBSession.query(MyModel).filter(MyModel.name == 'one').first()
    except DBAPIError:
        return Response(conn_err_msg, content_type='text/plain', status_int=500)
    return {'one': one, 'project': 'tutorial'}

このview_configってのがクラス名だったから、少し悩んだけど、
@の部分はインスタンス作成となり、__init__に引数を渡す。
デコレートする関数のmy_viewはインスタンス呼び出しの__call__でラップされる。

ってことだと思うけど、検証はまた今度。

18
18
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?