6

これは、matplotlib の csv2rec のソース コードからのものです。

パラメータが「func, default」のみの場合、この関数はどのように機能しますか?

def with_default_value(func, default):
    def newfunc(name, val):
        if ismissing(name, val):
            return default
        else:
            return func(val)
    return newfunc

ismissing は名前と値を取り、numpy 配列で行をマスクするかどうかを決定します。

func は、str、int、float、または dateparser のいずれかになります...データを変換します。たぶん重要ではない。「名前」と「値」をどのように取得できるのか疑問に思っています

私は初心者です。2セントありがとうございます!私は他の人を助けるのに十分になることを願っています!

4

4 に答える 4

8

このwith_default_value関数は、しばしば (不正確に) 「クロージャー」と呼ばれるものです (技術的には、クロージャーはむしろ返される内部関数です。here newfunc-- たとえばhereを参照してください)。より一般的にwith_default_valueは、高階関数("HOF") です。関数 ( func) を引数として取り、結果として関数 ( ) を返しますnewfunc

これをPythonのデコレータの概念と構造と混同する回答を見てきましたが、これは間違いなくそうfuncではありませんint. デコレータも高階関数ですが、より具体的なものです: 関数引数の装飾された、つまり「強化された」バージョンを返すもの (これは唯一の引数でなければなりません -- 「引数を持つデコレータ」は、デコレーター HOF に複数の引数を与えるのではなく、関数/クロージャーの入れ子)、その関数引数とまったく同じ名前に再割り当てされます (したがって、通常は同じ署名を持ちます-そうでない場合、デコレーターを使用することは非常に困難です)独特、非慣用的、判読不能など)。

そのため、ケースとはまったく関係のないデコレーターは忘れて、newfuncクロージャーに注目してください。字句的にネストされた関数は、囲んでいる関数のすべてのローカル変数名 (引数はローカル変数であるため、引数名を含む) を参照できます (ただし、再バインドはできません)。これがクロージャとして知られている理由です。これらを「閉じた」ものです。 「自由変数」。ここで、newfunc参照できるfuncdefaultします。

高階関数は Python では非常に自然なことです。特に、関数はファーストクラスのオブジェクトであるため (そのため、関数を引数として渡したり、関数値として返したり、リストや他のコンテナーに格納したりするために特別なことをする必要はありません)。など)、関数と他の種類のオブジェクトの間に名前空間の区別はなく、関数が言及されているという理由だけで関数の自動呼び出しはありません。この種の多くの区別を引き出します)。Python では、関数について言及することは、まさに言及です。CALL は、関数オブジェクト (名前などで参照) の後に括弧が続く場合にのみ発生します。

この例にあるのはこれですべてです。質問を編集したり、ここにコメントしたりしてください。他に不明な点がある場合は、お気軽にコメントしてください。

編集:したがって、OPは「クロージャーファクトリー」の例をもっと求めて丁寧にコメントしました。これが 1 つです -- 抽象的な種類の GUI ツールキットを想像してみてください。

for i in range(len(buttons)):
  buttons[i].onclick(lambda: mainwin.settitle("button %d click!" % i))

しかし、これは正しく機能しません。 isilambdaで遅延バインドされているため、いずれかのボタンがクリックされるまでに、どのボタンがクリックされたかに関係なく、iの値は常に最後のボタンのインデックスになります。さまざまな実行可能な解決策がありますが、クロージャ ファクトリはエレガントな可能性です。

def makeOnclick(message):
  return lambda: mainwin.settitle(message)

for i in range(len(buttons)):
  buttons[i].onclick(makeOnClick("button %d click!" % i))

ここでは、クロージャ ファクトリを使用して変数のバインド時間を微調整しています!-) 何らかの形で、これはクロージャ ファクトリのかなり一般的な使用例です。

于 2009-09-23T02:41:30.037 に答える
6

これは Python デコレータです。基本的には関数ラッパーです。(PEP 318 のデコレータについてすべて読んでください -- http://www.python.org/dev/peps/pep-0318/ )

コードをざっと見てみると、おそらく次のようなものが見つかります。

def some_func(name, val):
    # ...
some_func = with_default_value(some_func, 'the_default_value')

name 引数または val 引数のいずれかが欠落している場合 (おそらく、それらが None に設定されている場合)、このデコレータの意図はデフォルト値を提供するようです。

于 2009-09-23T01:55:59.913 に答える
1

なぜそれが機能するのかについて:

with_default_value は関数オブジェクトを返します。これは基本的にネストされた newfunc のコピーであり、'func' 呼び出しとデフォルト値が with_default_value に渡されたもので置き換えられます。

誰かが 'foo = with_default_value(bar, 3)' を実行すると、戻り値は基本的に新しい関数になります。

def foo(name, val):
    ifismissing(name, val):
        return 3
    else:
        return bar(val)

その戻り値を取得して呼び出すことができます。

于 2009-09-23T02:01:41.983 に答える
0

これは別の関数を返す関数です。 nameおよびvalueは、返される関数のパラメーターです。

于 2009-09-23T01:54:58.323 に答える