既に解決積みですが、重要な点なので和つぃなりの回答を載せておきます。
こういう質問をされる方は、関数オブジェクトと、関数オブジェクトがバインドされている変数の関係が良くわかっていないか、あるいは関数の定義と関数の実行の関係が良くわかっていない場合が多いです。
最初に 公式ドキュメント 4.2. 名前づけと束縛 (naming and binding)を読んで束縛(バインド)を理解してください。
- 関数オブジェクトと、関数オブジェクトがバインドされている変数の関係とは
maxという関数がありますが、これはmaxという名前が最大値を求める組込み関数に束縛されているということです。
例えば以下のコード実行で何が起きているかを理解してください。
python
1>>> maximum = max
2>>> print(maximum([1,2,3,0]))
33
4>>> print(maximum.__name__)
5max
maxmumもmaxもmaxという名前を持つ関数オブジェクトに束縛されている名前なのでどちらを使っても同じです。
次のコードはmaxとminの束縛を入れ替えるものです。
python
1>>> max, min = min, max
2>>> print(max([1,2,3,0]))
30
4>>> print(min([1,2,3,0]))
53
6>>> max, min = min, max
7>>> print(max([1,2,3,0]))
83
python
1def accumulate(a, b):
2 return a + b
このように関数を定義しても、足し算が実行されるわけではありません。
実行されたのは関数定義です。つまり足し算を行う関数オブジェクトが作られ、accumulateという名前がその関数オブジェクトに束縛されたのです。
この関数を実行してはじめて足し算が実行されます。
python
1>>> def accumulate(a, b):
2... return a + b
3...
4>>> print(accumulate(40, 2))
542
6>>> print(accumulate('Hello, ', 'Python'))
7Hello, Python
ご質問に戻ると、
python
1def logger(func):
2 def inner(*args):
3 print("引数:", args)
4 return func(*args)
5 return inner
によって、innerという関数定義を行って、できた関数を返すようなloggerという関数が定義されます。
loggerという関数は定義されましたが、まだloggerは実行されていないので、innerという関数は定義されていません。
python
1newfunc = logger(accumulate)
を実行したときにその右辺であるlogger(accumulate)が実行され、このときinnerという関数オブジェクトが生成されて、loggerのローカル変数であるinnerがその関数オブジェクトに束縛されます。このときのinnerの関数定義では、引数funcが束縛されているのはaccumulateという関数オブジェクトです。
loggerはinnerをreturnするので、logger(accumulate)はinnerが束縛されているinnerという関数オブジェクトを返します。
代入文ですので、newfuncという名前が生成されたinnerという関数オブジェクトに束縛されます。
python
1print(newfunc(1,2))
を実行すると、newfuncという名前が束縛されている関数オブジェクトが(1, 2)を引数として呼び出されます。この関数呼び出し、つまり関数の実行の中で、func(*args)が呼び出されますが、このローカル変数funcの中身は関数オブジェクトinnerが定義されたときのfuncですので、そのときfuncという名前に束縛されていたaccumulateという名前の関数オブジェクトです。従って、func(*args)は(1, 2)を引数としてaccumulateという名前の関数オブジェクトを呼び出すことになります。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/10/31 13:02