質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

816閲覧

デコレーターの順序とreturn

NealStallone

総合スコア3

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

1グッド

0クリップ

投稿2019/08/10 22:42

編集2019/08/10 23:13

前提・実現したいこと

python 初心者です。デコレーターの順序と
オブジェクトreturn の意味合いについてお尋ねいたします。

発生している問題・エラーメッセージ

1.呼び出し方法:
(13) a = add_suuji(dd_fo(18, 81))と考えて宜しいのでしょうか?

2.実行順序のイメージ:
「13 -> 1 -> 7 ( -> 2 -> 10 )->14」で宜しいのでしょうか?
「add_fo」は、2から実行し、その結果を 7 のreturnで戻しているのか、
先ずは、7 を実行し、return weapper の wrapper オブジェクト
参照で、2 のrapper 以降が実行されているのかが分かりませんでした。

3. return について:
7. は、「return(wrapper) 」ではなく「return wrapper 」とオブジェクトを
戻しているのはなぜでしょうか?
6 で result を 7 に戻し、7 の return で、13 の a に戻している
のでしょうか?

分かりづらく申し訳ございませんが、宜しくお願いいたします。

該当のソースコード

_1|....def add_fo(func): _2|........def wrapper(*args, **kwargs): _3|............print('----- START -----') _4|............result = func(*args, **kwargs) _5|............print('----- END -----') _6|............return result _7|........return wrapper _8| _9|....@add_fo 10|....def add_suuji(x, y): 11|........return x + y 12| 13|....a = add_suuji(18, 81) 14|....print(a)

試したこと

add_fo(func) の中で print()で実行順序を確認しましたが
まず「return wrapper」に制御が移っているように思えました。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

YouheiSakurai👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gentaro

2019/08/10 22:56

「初心者です」と書くなら「初心者アイコン」をつけておくとよいです。 頑張ってソースコードを整形して記載されてますが、質問文ではmarkdownという記法(ググってみよう)で簡単に整形されたソースを記述できます。 (ひょっとすると行番号をつけたくてこういう書き方をされたのかもしれませんが、コードの該当箇所にコメントを挿入するなど、書き方を工夫すれば行番号がなくても書けると思います) markdownの入力の方法がわからなければ質問文の入力欄に入力を補助する機能もあります。 https://teratail.com/help/question-tips#questionTips3-3-1 https://teratail.com/help#about-markdown また、箇条書きもmarkdownで可能です。 あと、ソースコードの下に入っている「通報する」という穏やかでない一文が気になります。 質問文は編集できるので適宜修正してみてください。
NealStallone

2019/08/10 23:18

お世話になります。 アドバイスをありがとうございました。 他画面からコピーして意図しない文言が貼り付けられていました。 1.アイコンつけさせていただきました(python も当サイトも初心者です)。 2.ソースは不自然なままですが、コードボタンを利用させていただきました。
gentaro

2019/08/10 23:28

ソースコードについては、現状の書き方だとコピペしてそのまま動かすことができない(行番号や位置揃えのための「.」などが入っている)ので、回答者が検証してみようと思ったときに不便なところが問題です。 そのため、コードボタンを押して出てくる```と```の間の行に実際に動かしているコードをコピーするのをお勧めします。 「ここに言語を入力」と書かれている箇所を「python」とかに上書きすると、言語名に応じてシンタックスハイライトが適用されて読みやすいのもメリットです。 さておき デコレータの説明としてはググると以下のような複数の説明記事がヒットしますが、読んで解決しないもんなんでしょうか? https://qiita.com/mtb_beta/items/d257519b018b8cd0cc2e https://qiita.com/_rdtr/items/d3bc1a8d4b7eb375c368 http://note.crohaco.net/2014/python-decorator/
guest

回答1

0

ベストアンサー

1.呼び出し方法:
(13) a = add_suuji(add_fo(18, 81))と考えて宜しいのでしょうか?

違いますね。
a = add_fo(add_suuji)(18, 81)
が正しいです。

2.実行順序のイメージ:
「13 -> 1 -> 7 ( -> 2 -> 10 )->14」で宜しいのでしょうか?

実行順序は、以下の数字の順序になりますね。
ちょっと意外?な点は add_suuji() が「定義されるとき」に (2) (3) が実行されることかなと思います。

print(0) def add_fo(func): print(2) def wrapper(*args, **kwargs): print(5) result = func(*args, **kwargs) print(7) return result print(3) return wrapper print(1) @add_fo def add_suuji(x, y): print(6) return x + y print(4) a = add_suuji(18, 81) print(8) print("-"*10) print(a)

※ デコレータは以下の処理と意味は同じです。以下のように書き直してもちゃんと動きます。

def add_suuji(x, y): .... add_suuji = add_fo(add_suuji)

「add_fo」は、2から実行し、その結果を 7 のreturnで戻しているのか、
先ずは、7 を実行し、return weapper の wrapper オブジェクト
参照で、2 のrapper 以降が実行されているのかが分かりませんでした。

add_fo は wrapper関数を定義し(wrapper関数の中身はこの時点では評価されない)、
その関数を返しているだけです。

3. return について:
7. は、「return(wrapper) 」ではなく「return wrapper 」とオブジェクトを
戻しているのはなぜでしょうか?

デコレータは「(関数を引数に取り、)関数をreturnする」関数です。
なので、必ず関数を返します。

6 で result を 7 に戻し、7 の return で、13 の a に戻しているのでしょうか?

たぶん、この辺がこんがらかっているのでしょうね...

7 は add_suuji() をCallしたときには呼ばれません(デコレートするときにだけ呼ばれている)。
add_foのデコレータは、add_suuji を置換する仕事をしたらその後はもう関係ないものになります。

投稿2019/08/10 23:57

mokemokechicken

総合スコア948

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

NealStallone

2019/08/11 01:09

お世話になります お礼の方法が合っているかわかりませんが 早々かつ詳細のご回答誠にありがとうございます 大変参考になりました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問