什么时候在Python中使用嵌套函数是好的?

时间:2013-06-10 22:25:58

标签: python

我不是指闭包,外部函数返回内部函数,或者特别是memoization。有几个实例我想写一个递归函数,也许有memoization,并且在外部函数中初始化字典或其他一些数据结构似乎更简单,然后有一个递归的辅助函数写入和访问dict和外部函数的参数。这就是我的意思 -

def foo(arr, l):
   cache = {}
   result = []

   def recursive_foo_helper(i, j, k):
      # some code that depends on arr, l, i, j, k, cache, and result

   for (x, y) in arr:
      if recursive_foo_helper(x, y, k):
         return result
   return None

而不是使用某些超长签名(

)单独声明辅助函数
recursive_foo_helper(arr, l, i, j, k, cache={}, result=[])

我已经读过,这样做对于memoization来说是非常标准的,但是我很好奇是否就可以为递归辅助函数做的事情达成共识。

4 个答案:

答案 0 :(得分:5)

我使用嵌套函数从列表中查找匹配项:

def get_exact(data, key, match):
    def is_match(item):
        if (key in item) and (item[key].lower() == match.lower()):
            return item
        return False
    return [i for i in data if is_match(i)]

项目中没有其他调用需要使用is_match(item),为什么要单独声明呢?

但是,我会说,对于我的例子,在get_exact()之外声明is_match()会在10,000次迭代中更快地运行~0.04 seconds

def is_match(item, key, match):
    if (key in item) and (item[key].lower() == match.lower()):
        return item
    return False

def get_exact(data, key, match):
    return [i for i in data if is_match(i, key, match)]

答案 1 :(得分:2)

我通常使用闭包,但是你建议的另一种方式(我有时称之为Wrapper)也非常有用,根据我的个人经验,它工作正常。我从来没有人告诉我要避免这种风格。如果您的代码有效并且可读(我认为是这样),那就去吧!

答案 2 :(得分:1)

我建议使用一个闭包,因为你建议更清晰,但如果你想重新引用引用,确实需要Python3的nonlocal关键字。对于可变对象,显然可以修改它们。

与此同时,在Python2中看到defaultarg hacks / idioms是很常见的

嵌套函数的一个(可能是唯一的)缺点是难以进行单元测试。

为了确保缓存无法无限增长,您还需要一种方法来删除项目(例如,最近最少使用的)

答案 3 :(得分:1)

有很多好的理由。就个人而言,我经常使用嵌套函数来保持名称空间的清洁。它在对象方法中特别有用:

class Foo(object):
    def bar(self):
        def baz(val):
            return val
        return [ baz(i) for i in range(1,101) ]

如果我在baz之外声明bar,我需要将其设为Foo的方法,或将其公开给整个包。

相关问题