関数デコレーターの動作

処理フロー

  1. 実行時、インタプリタがデコレーター割り付けを見つけると、直ちにそのデコレーター関数を呼び出す。関数の戻り値は関数オブジェクト(呼び出し可能:callable)であること。
  2. デコられた(被デコ)関数(例ではhello/hello2)を呼び出したときの動きとしては以下のようになる。
    1. 手順1の戻り値関数(例ではlambda/inner)を呼び出す。このときの第一パラメーターに被デコ関数オブジェクトを渡す。
    2. 手順2-2の戻り値関数(例ではhello/hello2)を呼び出す。

割り付けが見つかった時点でデコレーター関数が呼び出される。
「被デコ関数呼び出し直前にデコレーターを呼びだしたい!」という場合は
デコレーター割り付けを内包する関数を定義するのがよろしいかと思われる。

コード例

def mydecorator():
	print("this is decorator!!")
	return lambda f : f

def mydecorator2(num):
	def inner(func):
		for i in range(int(num)):
			print("this is innerdeco!!!!")
		return func
	return inner

#パラメーターなしデコレーター
@mydecorator()
def hello(name):
	print("hello, ",name)

#パラメーター付きデコレーター
@mydecorator2(3)
def hello2(name):
	print("hello, ",name)

#デコレーター割り付けを内包する関数
def call_hello(name):
	@mydecorator()
	def hello3(name):
		print("hello, ", name)
	hello3(name)

if __name__ == "__main__":
	hello2("john")
	call_hello("tom")