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

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

ただいまの
回答率

90.84%

  • Python

    5931questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

  • Python 3.x

    4461questions

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

  • 関数

    187questions

    関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

Python デコレータ、関数内関数について

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 143

miga

score 1

def f1(func):
    def hoge():
        print ("名前は、")
        func
    return hoge()


def f2(name):
    print (name)


f1(f2("佐藤"))


上記のコードで、実行結果が以下のようになってしまうのはなぜでしょうか。
佐藤
名前は、

hoge関数内の実行順で出力されることを期待していたのですが...

LouiS0616さん
追加で質問させていただいてよろしいでしょうか。

私が書いたコードの場合、f1(f2("佐藤"))によって、func=(print("佐藤"))が実行されるため、この時点で、「佐藤」が出力され、その後hoge関数によって「名前は、」が出力されため、
佐藤
名前は、
という出力順になるという認識で合っていますでしょうか。

また、以下のようにした場合、期待通りの結果が得られるのですが、どうして上記コードと出力結果が異なるのかが理解できません。

def f1(func):
    def hoge():
        print ("名前は、")
        print (func)
    return hoge()


def f2(name):
    return (name)


f1(f2("佐藤"))

初歩的な質問で申し訳ありませんが、ご回答いただけると幸いです。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • quiqui

    2018/05/18 19:49

    タイトルから「デコレータ」の語を削除しておいた方が良さそうですね。もう変更できないようなら、質問の冒頭に追記しておくべきかと。

    キャンセル

回答 3

checkベストアンサー

+3

f2を実行した返り値を、f1に渡しているからです。
ついでに記述が無駄になっている部分を省くと、次のように書いているのと同じです。

def f1(func):
    print ("名前は、")

def f2(name):
    print (name)


f2_result = f2("佐藤")
f1(f2_result)

『関数を関数に渡す』のと『関数の返り値を関数に渡す』のとでは全く違う結果になります。
デコレータの働きは前者、ご提示のコードは後者です。

質問追記を受けて

私が書いたコードの場合、...という出力順になるという認識で合っていますでしょうか。

いちおう確認しておきますが、関数hoge内においてfuncは呼び出されていません。

def hoge():
    print ("名前は、")
    func   # ← 呼び出さないと動かない

また、f2の返り値がf1に与えられているため、funcの値は実際はNoneです。
その点で、『func=(print("佐藤"))が実行される』という認識はちょっと怪しいです。

処理の順序は次のとおりです。

  1. f2が引数 "佐藤" を与えられて実行される。
    f2の内部では引数 "佐藤" を出力する。
  2. その返り値 None がf1の引数として与えられて実行される。
  3. f1内でhogeを定義し、それを引数なしで呼び出したものを返り値とする。
    hogeの内部では "名前は、" を出力する。
    ここでfuncは呼び出されていないし、そもそも呼び出せない。

また、以下のようにした場合、期待通りの結果が得られるのですが、どうして上記コードと出力結果が異なるのかが理解できません。

def f1(func):
    def hoge():
        print ("名前は、")
        print (func)
    return hoge()


def f2(name):
    return (name)


f1(f2("佐藤"))

処理の順序は次のとおりです。

  1. f2が引数 "佐藤" を与えられて実行される。
  2. その返り値 "佐藤" がf1の引数として与えられて実行される。
  3. f1内でhogeを定義し、それを引数なしで呼び出したものを返り値とする。
    hoge の内部では "名前は、" を出力する。
    さらに、f1 に与えられた引数 "佐藤" を出力する。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/18 14:08

    追加で質問させて頂きましたので、ご確認いただけると幸いです。

    キャンセル

  • 2018/05/18 19:29

    納得しました!ありがとうございます。
    基本的な知識が足りなかったようです。

    キャンセル

+3

やりたいのはこんな感じなのかなぁ。

In [9]: def f1(func):
   ...:     def hoge(name):
   ...:         print ("名前は、")
   ...:         func(name)
   ...:     return hoge
   ...:
   ...: @f1
   ...: def f2(name):
   ...:     print (name)
   ...:
In [10]: f2("佐藤")
名前は、
佐藤

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

何がしたかったのか推測する合戦になってますが。

def f1(func):
    def hoge(arg):
        print ("名前は、")
        func(arg)
    return hoge

def f2(name):
    print(name)

f1(f2)("佐藤")


結果

名前は、
佐藤

実態はtachikomaさんの回答と変わりありません。
f1は引数の名前から言っても関数を渡されることを期待していますね。f1(f2)と呼び出すことで関数が返ってきますから、f1(f2)(なにか引数)が関数呼び出しになります。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 90.84%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Python

    5931questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

  • Python 3.x

    4461questions

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

  • 関数

    187questions

    関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。