2017-04-23 12 views
1

私はPythonのエキスパートが、内部関数、クロージャ、ファクトリ関数で現在経験している混乱について助けてくれることを願っています。一般的なハフ変換の実装例を探している変換時に私はこれが見つかりました:Python - 内部関数、クロージャ、およびファクトリ関数 - どのように因数分解するのですか?

https://github.com/vmonaco/general-hough/blob/master/src/GeneralHough.py

(私はC++にこれを翻訳したいのですが、最初のステップは、general_hough_closureで内部機能を考慮することであると思われます) :

def general_hough_closure(reference_image): 
    ''' 
    Generator function to create a closure with the reference image and origin 
    at the center of the reference image 

    Returns a function f, which takes a query image and returns the accumulator 
    ''' 
    referencePoint = (reference_image.shape[0]/2, reference_image.shape[1]/2) 
    r_table = build_r_table(reference_image, referencePoint) 

    def f(query_image): 
     return accumulate_gradients(r_table, query_image) 

    return f 

この機能の仕組みにはまっているようです。 "f"はどこにも呼び出されていないようで、関数がどのように "query_image"を知っているのか分かりません。私は内部の関数、クロージャ、ファクトリ関数のヒントを見つけるためにさまざまなグーグルを試しました。例えばthisと類似のページですが、私が見つけることができるすべての例はより簡略化されており、あまり役に立ちません。誰かが何らかの方向を提示できますか?

+0

このコードでは、__ *リターンがfunction__を*。あなたはそれがあなたが望んでいると確信していますか?私はそれがあなたがC++でやりたいと思うことではないかと疑っています。 –

+0

@Rawing、私は関数が関数を返すことを知っています。それは除外したい部分ですので、C++に翻訳できます – cdahms

+0

'def f(query_image)'行を削除し、 'return f '関数に、' query_image'という名前の2番目のパラメータを与えます。それは翻訳しやすいはずです。 –

答えて

0

コードはちょうどです。関数fを返すだけです。 「引数が何であるかを知る必要はありません。fは呼び出された時点でそれを知っています。まだその実引数を期待しながら、gは、の上に別の値を(xまたはr_table、それぞれ)閉じてあなたの関数のように、ここで

>>> def f(x): 
...  def g(y): 
...   return x + y 
...  return g 
... 
>>> f 
<function f at 0x7f8500603ae8> 
>>> f(1) 
<function f.<locals>.g at 0x7f8500603a60> 
>>> s = f(1) 
>>> s(2) 
3 

:古典的な例はこれです。

クローズオーバーの値があるため、fを直接除外することはできません。 1つの従来のアプローチは、値を含むオブジェクトを返すことです。このオブジェクトには、関数を表す何らかの種類の呼び出しメソッドがあります。最近はC++で簡単な方法は、ラムダ関数を使用することです:Cで

int f(int x) { 
    auto g = [x](int y) { 
    return x + y 
    }; 
    return g; 
} 

を++、あなたはそれがここに[x]だ(あなたがオーバークローズされている値を指定しない場合、それはあなたに叫ぶだろうという「利点」を持っています)。しかし、内部的には、ほとんど同じことをしています(x-memberで匿名クラスを構築しています)。

+0

私のC++が整形式でない場合は、それを編集してください。私は実際にC++を頻繁に使用しません。 – phg

0

C++ 11より前のC++では、型としての機能がありません。

あなたはセマンティクス(擬似コード)をエミュレートするために以下のクラスを使用することができます。

class GeneralHoughClosure { 
    public: 
    GeneralHoughClosure(reference_image) { 
     referencePoint = (reference_image.shape[0]/2, reference_image.shape[1]/2) 
     r_table = build_r_table(reference_image, referencePoint) 
    } 
    void Run(queryImage) { 
     return accumulate_gradients(r_table, query_image) 
    } 
    void operator()(queryImage) { 
     return accumulate_gradients(r_table, query_image) 
    }   
    } 

すると、次のようにあなたがそれを使用することができます。

gg = new GeneralHoughClosure(reference_image) 
gg.Run(queryImage1) 
gg(queryImage2) 
+0

提案をお寄せいただきありがとうございます。クラスを追加せずに入れ子関数を除外する方法はありますか? – cdahms

+0

C++ 11には型としての関数があります。 [std :: function](http://en.cppreference.com/w/cpp/utility/functional/function)を初期設定して返すことができます(例えば、http://en.cppreference。com/w/cpp/language/lambda)を使用しています。 – mdavezac

+0

あなたは正しいです、私は答えを更新しました。 私たちの中には、C++ 11でうまく動作しない人がいます:-) – napuzba

関連する問題