デコレータ

入門Python3 4.9


デコレータという名前がついてますが、内容は凄く単純です。

まずは物凄くシンプルに実装してみたデコレータを見てみましょう。

def bar(func):
    return "bar"

@bar
def foo():
    pass

print(foo)
$ py main.py
bar

foo関数定義の前に@barと書くだけです。

fooが関数ではなく、"bar"という文字列に変わっています。

じつはこれ以下の処理とまったく同じことをしています。

def bar(func):
    return "bar"

def foo():
    pass
foo = bar(foo) # @barとまったく同じ意味

print(foo)

デコレータとは単にそれだけのことですね。

上記例ではbar関数で文字列を返していますが、本来は関数を受け取って関数を返す処理を書くのが正しい使い方となります。


でどういう使い道があるのかというと、例えばある関数の実行前と実行後に何か処理をしたいといった場合ですかね。

def bar(func):
    def inner():
        print("start func")
        func()
        print("end func")
    return inner

@bar
def foo1():
    print("foo1")
    
@bar
def foo2():
    print("foo2")

foo1()
foo2()
$ py main.py
start func
foo1
end func
start func
foo2
end func


またデコレータは複数設置することもできます。

その場合下から上へと順にデコレータが適用されていきます。

def bar1(func):
    def inner():
        print("bar1 start func")
        func()
        print("bar1 end func")
    return inner
    
def bar2(func):
    def inner():
        print("bar2 start func")
        func()
        print("bar2 end func")
    return inner

@bar2
@bar1
def foo():
    print("foo")

foo()
$ py main.py
bar2 start func
bar1 start func
foo
bar1 end func
bar2 end func

他にも色々応用できそうですね。