2009-09-23 20 views
6

これはmatplotlibのcsv2recソースコードからのものですこのPython関数コードはどのように機能しますか?

唯一のパラメータが '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セントありがとう!私は他人を助けるために十分に良いことを望む!

+1

「if ismissing」のようなスペースはありませんか? @with_default_value(some_func、 'the_default_value') DEF some_func(名前、ヴァル):あなたが前に(@構文を使用している場合 #... – recursive

答えて

8

このwith_default_value機能は、多くの場合、「閉鎖」( - 例えばhereを参照してくださいここで返されるインナー機能、newfuncではなく、技術的、閉鎖がある)として(不正確)と呼ばれるものです。より一般的にはwith_default_valueは高次関数( "HOF")であり、引数として関数(func)をとり、結果として関数(newfunc)も返します。

私はデコレータコンセプトでこれを混乱答えを見て間違いない場合ではPythonで構築しました - あなたはfuncは、できるだけ頻繁にビルトインされているなどintとして言及し、特に以来。デコレータも高次関数ですが、デコレータは具体的なものです。デコレータHOFに複数の引数を指定することにより、の引数である "enriched"バージョン(引数のみ - 引数のあるデコレータは、もう1つのレベルのファンクション/クロージャのネストによって取得されます。ではなく)その関数の引数とまったく同じ名前に再割り当てされます(通常は同じシグネチャを持ちます。そうでなければデコレータを使用すると、が極端にという特殊な、慣れない、読めないなど)。

したがって、ケースとはまったく関係のないデコレータを忘れて、newfuncクロージャに注目してください。字句的にネストされた関数は、囲み関数のすべてのローカル変数名(引数がローカル変数であるため、引数名を含む)を参照することができます。これがクロージャーとして知られています。 "自由変数"。ここで、newfuncは、funcおよびdefault-を参照することができます。

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

これはこの例のすべてです。疑問に残っている他の特定の側面がある場合は、質問を編集したり、ここでコメントしたりしてください。

を編集します。したがって、OPは「閉鎖工場」の例を丁寧に尋ねています。ここでは1だ - GUIツールキットのいくつかの抽象の種類を想像して、あなたは何をしようとしている:

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

が、これは正しく動作しません - ilambda内の時間ずつので、遅延バインディングされますボタンがクリックされた場合iの値はいつでもの最後のボタンのインデックスになります。そこ様々な実行可能解であるが、閉鎖工場のエレガントな可能性:!

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

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

、我々は変数の結合時間を微調整するために閉鎖工場を使用している - )1つの特定のフォームまたは別では、これは、 closureファクトリのかなり一般的な使用例です。

+0

私は訂正したと思います。区別をつけてくれてありがとう。このHOFはどのように呼び出されるのでしょうか? – dcrosta

+0

@dcrosta、私はこのイディオムの正式な名前を持っていません - ほとんどのHOFがクロージャを返すように、私はそれを関数のファクトリを実装する便利な方法と考えています。 –

+0

偉大な答え、それは戦いだった、私は他の男がそれを持っていると思った、そしてあなたはタッチダウンのために来る!ありがとう私は皆が何かを学んだと思う!私はあなたがこれの他の例を持っているのだろうかと思いましたか?ちょっと興味があるんだけど。それを見つけるのが非常に難しい場合は心配はありません。 – Pete

0

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

6

これはPythonデコレータで、基本的には関数ラッパーです。

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

このデコレータの意思があれば、デフォルト値を供給するようだ:あなたはコードを見れば、あなたはおそらくこのような何かを見つけるでしょう

- (http://www.python.org/dev/peps/pep-0318/ PEP 318でデコレータについての全て読みます) name引数またはval引数のいずれかが欠落しています(おそらく、Noneに設定されている場合)。それが動作する理由については

+0

はまさに、その新しいコードを除いて、一般的に多くのようになります。関数定義)、あなたはデコレータファクトリを持っていなければなりません(これは純粋なdeorator - 2レベルの深さです)。デコレータファクトリは引数を受け入れるかもしれませんが、必要はありません。これは3.xで変更されていない限り –

+0

と思う – dcrosta

+0

@dcrosta:私はそうは思わない。私は両方の構文を互換性のあるデコレータで使用していました。2.Xでは悪影響がありません – priestc

1

:基本的には「FUNC」コールとに渡されたものは何でもしてsubstitedデフォルト値で、そのネストされたnewfuncのコピーあることを行っている関数オブジェクトを返しますwith_default_value

with_default_value。

誰かが「FOOを= with_default_value(バー、3)」ない場合、戻り値は、基本的に新しい機能になるだろう:

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

ので、あなたは、その戻り値を取り、それを呼び出すことができます。

関連する問題