This function with_default_value is what is often referred to (inaccurate) as a "closure" (technically, closure is more likely an internal return function, here is newfunc - see, for example, here ). In general, with_default_value is a higher order function (HOF): it takes a function ( func ) as an argument, and also returns a function ( newfunc ) as the result.
I saw answers confusing this with the concept of a decorator and constructing in Python, which is definitely not not , especially since you mention func as being often inline, like int . Decorators are also functions of a higher order, but rather specific: those that return decorated, i.e. The "enriched" version of the argument of its function (which should be the only argument - "decorators with arguments") gets another function / close level, rather than giving the HOF decorator more than one argument), which is reassigned with the same name as this function argument (and, as a rule, has the same signature), using a decorator, otherwise it would be extremely peculiar, idiomatic, unreadable, etc.).
So forget the decorators that have absolutely nothing to do with it, and focus on closing newfunc . A lexically nested function can refer to (although not restore) all local variable names (including argument names, since the arguments are local variables) of the enclosing function (s) - therefore it is called closure: it "closes" above these "free variables". Here newfunc can refer to func and default - and does.
Higher-order functions are very natural in Python, especially since functions are first-class objects (so you have nothing to do to pass them as arguments, return them as function values, or even store them in lists or other containers, etc.), and there is no difference between the namespace between functions and other kinds of objects, without automatically invoking functions just because they are mentioned, etc. etc. (It's harder - a little harder or much harder in other languages ββthat make a lot of differences of this kind). In Python, mentioning a function is simple: mentioning; CALL occurs only when and when a function object (by name or otherwise) is followed by parentheses.
Regarding all this example, please feel free to edit your question, comment here, etc., if there is any other aspect that you doubt!
Edit : therefore, the OP commented politely on other examples of βclosing factories.β Here is one - imagine some abstract kind of GUI toolkit, and you are trying to do:
for i in range(len(buttons)): buttons[i].onclick(lambda: mainwin.settitle("button %d click!" % i))
but this does not work correctly - i in lambda is late, so by the time you press one button i value will always be the index of the last button, no that was pressed. There are various possible solutions, but closing the factory is an elegant opportunity:
def makeOnclick(message): return lambda: mainwin.settitle(message) for i in range(len(buttons)): buttons[i].onclick(makeOnClick("button %d click!" % i))
Here we use the factory closure to adjust the variable binding time! -) In one form or another, this is a fairly common precedent for closing factories.