我不是指闭包,外部函数返回内部函数,或者特别是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来说是非常标准的,但是我很好奇是否就可以为递归辅助函数做的事情达成共识。
答案 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
的方法,或将其公开给整个包。