When is it useful to use nested functions in Python?

I do not mean closure where an external function returns, in particular, an internal function or memoization. There were several cases where I wanted to write a recursive function, possibly with memoization, and it was much easier to initialize a dictionary or some other data structures in an external function, and then have a recursive helper function, access to the dict, and arguments to the external function. Here is what I mean -

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 

instead of having a helper function declared separately with some super long signature like

 recursive_foo_helper(arr, l, i, j, k, cache={}, result=[]) 

I read that this is pretty standard for memoization, but I was curious if there was a consensus as to whether this should be done only for recursive helper functions.

+6
source share
4 answers

I use a nested function to find matches from a list:

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

No other calls in the project need to use is_match (item), so why declare them separately?

However, I will say that for my example, the declaration of is_match () outside get_exact () is faster than ~0.04 seconds in 10,000 iterations.

 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)] 
+4
source

I usually use closures, however the other way you suggest (what I sometimes call Wrapper) is also very useful, and it works fine in my personal experience. I never told anyone to avoid this style. If your code works and reads (I think it is), then go for it!

+2
source

I would say that using closure, as you suggest, is cleaner, but in fact the nonlocal from Python3 requires link reissue. For mutable objects, it is obvious that they can be modified.

At the same time, a general understanding of defaultarg hackers / idioms in Python2

One (perhaps only) drawback of a nested function is that it is difficult to execute.

To make sure that the cache cannot grow indefinitely, you also need a way to delete items (for example, recently used)

+1
source

There are many good reasons. Personally, I often use nested functions to keep the namespace clean. This is especially useful in object methods:

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

If I declare baz outside of bar , I need to either make it the Foo method, or set it to the whole package.

+1
source

Source: https://habr.com/ru/post/946995/


All Articles