2017-04-23 72 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

此代碼__ *收益* A function__:

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) } } 

然後,您可以按以下方式使用它。你確定這就是你想要的嗎?我懷疑你想在C++中做什麼。 –

+0

@Rawing,我知道函數返回一個函數,這是我想分解的部分,所以我可以翻譯成C++ – cdahms

+0

刪除行'def f(query_image):',remove'return f ',給函數一個名爲'query_image'的第二個參數。這應該很容易翻譯。 –

回答

0

該代碼只是返回函數f作爲一個整體的事情。沒有必要「知道什麼是論據」 - f在它被調用時會知道它。最典型的例子是這樣的:

>>> 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 

在這裏,你的功能,g關閉了另一個值(xr_table,分別),但仍期待它的實際參數。

由於存在封閉值,因此不能直接分解出f。一種傳統的方法是返回一個包含該值的對象,該對象具有某種代表該函數的調用方法;在C++中更簡單的方法現在是使用lambda函數:

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

在C++中你有「優勢」,它會罵你,如果沒有指定哪些值你結束了(這是這裏的[x] )。但是在內部,它幾乎完成了同樣的事情(構造一個帶有x成員的匿名類)。

+0

如果我的C++格式不正確,請只編輯它,我實際上並不經常使用C++。 – phg

0

C++ 11之前的C++沒有函數作爲類型。

您可以使用下面的類來模擬語義(僞代碼):

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),用(lambda)(http://en.cppreference)初始化(例如)。com/w/cpp/language/lambda),就像你在python中一樣。 – mdavezac

+0

你是對的,我更新了答案。 我們中的一些人沒有奢侈品與C++ 11一起工作:-) – napuzba