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

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

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

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

関数

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

Python

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

Q&A

解決済

2回答

211閲覧

[python3]この関数の説明をしていただけないでしょうか

matsukogo

総合スコア8

Python 3.x

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

関数

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

Python

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

0グッド

1クリップ

投稿2017/12/06 15:42

python初心者のものです。

あるサイトで初心者用のデコレータ関連の記事を読んでいて自分でコードを書いていじっていたところ、
どうしても仕組みを理解できない関数(といっていいのかわかりませんが…)が出来上がってしまいました。
エラーが発生しないので、ますますわかりません。どなたか教えていただけないでしょうか。

コードは下記です。

python3

1def scramble(egg): 2 def _scramble(): 3 return "scramble " + egg() + "!" 4 return _scramble 5 6def potato(): 7 return "egg" 8 9if __name__ == '__main__': 10 scramble_egg = scramble(potato) 11 print(scramble_egg()) 12 13#scramble egg! が表示されます

scramble()関数を引数potatoで呼び出すということだと思うのですが、
potato()関数がないと「potatoが定義されていない」というエラーになります。
potato()は一切かかわていないと思うのですが…。

ためしにtypeで型を調べてみました。

python3

1print(type(potato)) #func 2print(type(potato())) #str 3

これはつまりscramble()の引数potatoは関数で、
関数が呼ばれてeggがreturnされ、scramble()の引数にeggが入ったということでしょうか?

よろしくおねがいします。

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

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

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

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

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

guest

回答2

0

名前の付け方が少し混乱しているようなので整理してみました。これはクロージャという手法(仕組み?)ですが、リスト内包記法と同様に頭が慣れるまでは難しく感じるかもしれません。コメントも追加したので参考にしてみてください。

python

1def scramble(fn): 2 '''関数を受け取って少し手を加えた関数を返す 3 4 関数に手を加えるのでデコレーターとも言います 5 ''' 6 def closure(): 7 return "scramble " + fn() + "!" # 元の関数を呼び出してその戻り値に手を加えて返します 8 return closure # 元々の関数ではなくて関数の中で定義した関数を返します 9 10def potato(): 11 return "potato" 12 13@scramble # 特殊な書き方でこう書くと関数がデコレートされます 14def egg(): 15 return "egg" 16 17if __name__ == '__main__': 18 print(egg()) # すでにデコレート済みなので「scramble egg!」と表示 19 scramble_potato = scramble(potato) 20 print(scramble_potato()) # 上の行で素のpotatoをデコレートしたので「scramble potato!」と表示

投稿2017/12/06 16:17

YouheiSakurai

総合スコア6142

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

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

matsukogo

2017/12/07 00:53

ご丁寧にありがとうございます。デコレータもクロージャもいろんな説明を読んだのですが、理解するにはまだかかりそうです・・・。ご説明いただいた内容を参考にさせていただきます。取り急ぎ感謝申し上げます。
guest

0

ベストアンサー

これはつまりscramble()の引数potatoは関数で、
関数が呼ばれてeggがreturnされ、scramble()の引数にeggが入ったということでしょうか?

その認識は異なります。Pythonでは、関数そのものを渡すことが可能です。

Python

1def hoge(): 2 print('hoge') 3 4def spam_ham(func): 5 print('spam') 6 func() 7 print('ham') 8 9spam_ham(hoge) 10 11"""実行結果 12spam 13hoge 14ham 15"""

関数の実行結果が渡されるわけではありません。
(実行されてから渡されるなら、第一行目にhogeと表示されるはず)


上記の例に加えて、こちらの例も示したいと思います。

Python

1def fuga(): 2 return 'fuga' 3 4func = fuga # 関数を代入 5text = fuga() # 関数の実行結果を代入 6 7print(type(func)) # <class 'function'> 8print(type(text)) # <class 'str'> 9 10func() # 関数は呼び出せる 11# text() # 関数じゃないから呼び出せない

これ以降、デコレータとは何ぞや、クロージャとは何ぞや、という理解が必要ですが、
そちらに関しましてはYouheiSakuraiさんの非常に丁寧かつ明確な回答をご覧ください。

投稿2017/12/06 15:55

編集2017/12/08 10:41
LouiS0616

総合スコア35660

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

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

matsukogo

2017/12/07 00:47

ありがとうございます。大変理解が深まりました。クロージャやデコレータに関してはいまだにイマイチ理解ができていない部分が多いので今後勉強していきます。取り急ぎ感謝申し上げます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問