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

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

ただいまの
回答率

90.53%

  • Python 3.x

    9390questions

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

Pythonにて、高階関数が理解できないので、

解決済

回答 1

投稿

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

tatsuya_055

score 5

お世話になります。
Tatsuyaと申します。

只今"みんなのPython 第4版"という本を読みながら
プログラミングの勉強をしているのですが、
高階関数のサンプルプログラムの中で理解できない箇所があり、
ご相談させていただきました。

def logger(func):
    def inner(*args)
        print('引数:', args)
        return func(*args)
    return inner

def accumulate(a, b):
    return a+b

newfunc = logger(accumulate)
print(newfunc(1, 2))


出力結果
引数:(1, 2)
3

上記プログラムのinner(*args)にaccumulate(a, b)の引数(a, b)が渡される理由が理解できません。

そもそも、関数の引数として関数が渡されるとどういった順序で引数側の関数に引数が渡され、
処理されるかといったことも理解てきておりません。。
また、上記の出力するためのコードも

logger(accumulate(1, 2))


ではなく、

(logger(accumulate))(1, 2)


となっているように感じるのですが、
認識誤りでしょうか?
仮に、下記になっている場合どのような処理となるのか、
お教えいただけると大変助かります。

お手数をおかけいたしますが、
ご教示いただけますと幸いです。

よろしくお願いいたします。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

+3

logger(accumulate)が呼び出されたとき、innerが返されますよね?
これは関数オブジェクトを返しているということで、それをnewfuncが受け取っているので、
newfunc = innerということになります。

innerが返される前にloggerで渡された引数により、返されるinnerは

def inner(*args)
        print('引数:', args)
        return accumulate(*args)


こうなります。
つまり、newfunc(1, 2)という呼び出しは、inner(1, 2)ということになりprint関数が呼ばれた後にreturnでacuumulate(1, 2)の結果が返されるということになるのです。

pythonの関数がオブジェクトだというのは、

print(logger.__class__) #<class 'function'>


この結果をみれば分かると思います。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/02/04 22:41

    fue様
    迅速なご回答ありがとうございます!

    つまり内部的(?)にinner = logger(accumulate)となり、
    その後、inner(1, 2)となり、定義された処理がされるのですね。

    おかげさまで次の問題へ進めそうです。
    大変勉強になりました。

    この度はお世話になりました。
    ありがとうございます!

    キャンセル

  • 2017/02/04 22:54

    いえいえ、自分も修行中の身なので。勉強がんばってください!

    キャンセル

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

  • Python 3.x

    9390questions

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