簡體   English   中英

Python - 內部函數,閉包和工廠函數 - 如何分解?

[英]Python - Inner Functions, Closures, and Factory Functions - how to factor out?

我希望那里的Python專家可以為我目前在內部功能,閉包和工廠功能方面遇到的困惑提供一些幫助。 在尋找General Hough Transform的實現示例時,我發現了這個:

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”是什么? 我嘗試了各種谷歌搜索,找到關於內部功能,閉包和工廠功能的提示,例如這個和一些類似的頁面,但我能找到的所有例子都更加簡化,因此沒什么幫助。 任何人都可以提供一些方向嗎?

代碼只是返回函數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 -member的匿名類)。

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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM