Pythonのデコレータについて、自分なりの理解をメモとして残しておきます。
まずは関数の性質理解
()をつけなければオブジェクトのように利用することができ、変数に入れて利用できる。
def function():
print('This is function')
function
# 実行結果
# <何も起きない>
function()
# 実行結果
# This is function
print(function)
# 実行結果
# <function function at XXXXXXXXXXX>
print(function())
# 実行結果
# This is function
# None
func = function
func()
# 実行結果
# This is function
関数の中での関数定義
関数の中で関数を定義し、利用することができる。
def outer_function():
def inner_function():
print('We can define function in function')
inner_function()
outer_function()
# 実行結果
# We can define function in function
デコレータ (関数を引数として受け取り、関数を返り値として返す関数)
以下、参考にしたWebサイト
デコレータは関数を引数として受け取り、関数を返り値として返す関数のことである。
以下の例の中でデコレータはouter_functionであり、function関数の前後にアスタリスクをprintする処理をデコレートし、inner_function関数として返す。
def outer_function(func): # 関数を引数として受け取る。
def inner_function():
print('******************')
func() # outer_function関数で引数として受け取った関数をinner_function関数内で利用できる。
print('******************')
return inner_function # 関数を返り値として返す。
def function():
print('This is function')
f = outer_function(function) # outer_function関数にfunction関数を渡し、変数fにはinner_function関数が返り値として代入される。
f() # 返り値として代入されたinner_function関数が実行される。
# 実行結果
# ******************
# This is function
# ******************
引数のある関数をデコレートする時は以下のとおりになる。
def outer_function(func):
def inner_function(x):
print('******************')
func(x)
print('******************')
return inner_function
def function(x):
print(x)
f = outer_function(function) # function関数の前後でアスタリスクをprintするinner_function関数がfに代入される。
f('HeroKey') # 返り値として代入されたinner_function関数にHeroKeyを引数として渡すことで、inner_function関数内のfunction関数にHeroKeyを引数として渡すことができる。
# 実行結果
# ******************
# HeroKey
# ******************
@を利用したデコレーション
@を使ってデコレーションすることで、記述を簡略化することができる。
def outer_function(func):
def inner_function(x):
print('******************')
func(x)
print('******************')
return inner_function
@outer_function
def function(x):
print(x)
# イメージとしては以下のようなことが行われるイメージ。
# function = outer_function(function)
# function関数をouter_function関数でデコレートしている。
function('HeroKey')
# 実行結果
# ******************
# HeroKey
# ******************