Python - 内部函数,闭包和工厂函数 - 如何分解?

时间:2017-04-23 11:11:22

标签: python

我希望那里的Python专家可以为我目前在内部功能,闭包和工厂功能方面遇到的困惑提供一些帮助。在寻找一般Hough变换的实现例子时,我发现了这个:

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"是什么?我尝试了各种Google搜索来查找内部函数,闭包和工厂函数的提示,例如this和一些类似的页面,但我能找到的所有示例都更加简化,因此帮助不大。任何人都可以提供一些方向吗?

2 个答案:

答案 0 :(得分: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),同时仍然期望其实际参数。< / p>

由于存在结算值,因此您无法直接将f分解出来。一种传统的方法是返回一个包含该值的对象,该对象具有某种表示该函数的调用方法;现在C ++中更简单的方法是使用lambda函数:

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

在C ++中,你拥有&#34;优势&#34;如果你没有指定你要关闭的值(这里是[x]),它会对你大喊大叫。但是在内部,它几乎完全相同(构建一个带有x成员的匿名类)。

答案 1 :(得分: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)