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

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

新規登録して質問してみよう
ただいま回答率
85.35%
オブジェクト

オブジェクト指向において、データとメソッドの集合をオブジェクト(Object)と呼びます。

関数

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

Python

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

Q&A

解決済

4回答

1176閲覧

関数内の関数に括弧がついていないにもかかわらず引数が渡されている。

naonao9423

総合スコア2

オブジェクト

オブジェクト指向において、データとメソッドの集合をオブジェクト(Object)と呼びます。

関数

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

Python

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

0グッド

0クリップ

投稿2020/11/14 11:12

質問したいこと

関数内に関数があるときに、関数の中にある関数に括弧も引数もないにもかかわらず、その関数の中にある関数に引数が実際には渡されていて計算が実行されていること。

質問したい内容としては
0. この本質である関数内に引数が渡されていないにもかかわらず実際は引数が渡されている原理や過程をわかりやすく教えていただけると嬉しいです

  1. この仕組みを書くにはどのようなコードの書き方をしたらいいのか。

該当のソースコード

_rexp.sub(_replace,string)の中の_replaceにはかっこが入っていないにもかかわらず
def _replace(m)とmという引数が設定されていてその引数も与えられている。

import sys, re def f(string): print(_rexp.sub(_replace, string)) return _rexp.sub(_replace, string) #<- 第1引数に関数を指定、  #_replaceには引数や括弧が書かれていない _rexp = re.compile(r'\{(\w+)\}') def _replace(m): #<- 引数の「m」は正規表現のマッチデータ key = m.group(1) frame = sys._getframe(2) #<- f()の呼び出し元のスタックフレーム try: if key in frame.f_locals: #<- ローカル変数を検索し、 return str(frame.f_locals[key]) #<- 置換する。 if key in frame.f_globals: #<- グローバル変数を検索し、 return str(frame.f_globals[key]) #<- 置換する。 return "{%s}" % key #<- なければ置換しない。 finally: del frame ## 使い方 w = 2560 h = 1600 print(f("width={w}, height={h}"))

試したこと

自分なりにre.pyを調べてみたり、検索してみたのですがあまりこれに該当するものは出てこなく、括弧をつけない関数はfunctionオブジェクトになるというような関係のサイトしか出会えませんでした。

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

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

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

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

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

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

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

guest

回答4

0

  1. この本質である関数内に引数が渡されていないにもかかわらず実際は引数が渡されている原理や過程をわかりやすく教えていただけると嬉しいです

わかりやすく言うと「そのようにre.subが定義されているから」です。

公式ドキュメント 正規表現操作-モジュールコンテンツのre.subの説明では「repl が関数であれば、それは重複しない pattern が出現するたびに呼び出されます。この関数は一つの マッチオブジェクト 引数を取り、置換文字列を返します。」と書いてあります。よって、関数が書かれている場合、このような定義にしたがって、何回か関数が呼び出され、その返り値が置換文字列として使われることになっています。

このような関数を引数にとるメソッドや関数は、Pythonだけでなく、最近の普通の言語には数多く存在します。関数を引数とする関数を、「高階関数」と呼び、最近(ここ30年くらい?もっとかも)の言語の特徴になっています。

  1. この仕組みを書くにはどのようなコードの書き方をしたらいいのか。

高階関数は、簡単に定義することが可能です。以下で例を示します。

Python

1class A: 2 x = [] 3 def agg(self, f): 4 return f(self.x) 5 6a = A() 7a.x = [1, 2, 3] 8print(a.agg(sum)) 9#6 10print(a.agg(max)) 11#3 12 13def diff_end_start(x): 14 return x[-1]-x[0] 15 16print(a.agg(diff_end_start)) 17#2 18print(a.agg(lambda x: x[-1]-x[0])) 19#2

この例のクラスAは、リストをメンバ変数として保持します。また、クラスAのメソッドaggは関数を引数に取り、メンバ変数のリストをその関数に与えて結果を出すような機能になっています。関数としては既成のものだけでなく、もちろん新たな関数を自分で定義してもよく、それを1行で書くラムダ関数という表記を使っても良いです。

投稿2020/11/14 11:49

編集2020/11/14 11:54
toast-uz

総合スコア3266

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

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

0

関数オブジェクトってやつですね
関数も他のクラスと同様、オブジェクトとして変数に入れたり関数に渡したりできます
そして、その関数の中で実行させることができるというはなしになります

投稿2020/11/14 11:43

y_waiwai

総合スコア88042

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

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

0

ベストアンサー

関数内で内部的に呼び出されています。

  1. この本質である関数内に引数が渡されていないにもかかわらず実際は引数が渡されている原理や過程をわかりやすく教えていただけると嬉しいです
  2. この仕組みを書くにはどのようなコードの書き方をしたらいいのか。

例えば、こんなふうに。

Python

1def my_convert(f, raw): 2 return f(raw) 3 4a = my_convert(int, '42') 5print(type(a), a) 6 7b = my_convert(list, '42') 8print(type(b), b) 9 10 11def peek(arg): 12 print(f'arg is {arg}') 13 return arg 14 15c = my_convert(peek, '42') 16print(type(c), c)

実行結果 Wandbox

<class 'int'> 42 <class 'list'> ['4', '2'] arg is 42 <class 'str'> 42

投稿2020/11/14 11:37

編集2020/11/14 11:38
LouiS0616

総合スコア35668

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

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

naonao9423

2020/11/14 11:45

早速の返信ありがとうございました! 自分の頭の中で引数にはintやlistなどの”値”しか入れられないと勝手に思い込んでしまってました。 関数内にfunctionのオブジェクトを入れることができることを知れてよかったです。 実際にコード例を入れてくださったのでLouiSさんをベストアンサーにさせていただきます。 ありがとうございました。
LouiS0616

2020/11/14 11:51

Pythonでは数値などの一般に想像する『値』と、関数オブジェクトを特に区別していません。 特徴の一つだったりします。(モダンな言語だと珍しくないですが)
guest

0

詳細はsub()の実装を見ないと分かりませんがcallbackで実行していると想像します。
(sub()が内部で引数で渡した_replace()に引数を付与して実行している)

公式の説明
https://docs.python.org/ja/3/library/re.html#text-munging

投稿2020/11/14 11:36

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問