A decorator is just a function that takes a function and returns a function. As this often involves nested functions, it's common to access the argument function via the closure, where the inner function captures its environment, but I suppose you could implement that with a partial instead, where the values are passed in explicitly. It's not clear quite what you'd like to know.
– jonrsharpeMay 5 '16 at 16:26

3 Answers
3

Short answer: closure is the mechanism, while functools.partial and decorators are typical uses of that mechanism.

The key difference between a closure and more typical namespaces is that the names and values in the "closed-over" namespace don't vanish when control flow leaves the top-level function. They're preserved in a mini-namespace associated with one instance of the inner function, and which survives as long as that instance does.

functools.partial uses that ability to "remember" some arguments to a pre-existing function. Decorators also typically use that ability for the same reasons.

Note that a decorator is more flexible than that. Any callable that takes one parameter and returns something can serve as a decorator. It doesn't have to make use of Python closures, or even return a function. Many decorators return a callable object instead. (As an aside, a closure and inner function can be simulated using an object for the namespace and a method for the inner function.)

Whatever the decorator returns is assigned to the name the decorated function would have had. (Decorators with parentheses after them, like @decorator('args') ... are slightly more complicated.) The typical decorator syntax:

I think you're confusing purpose with implementation. Creating a closure is a technique for doing things. You can do a bunch of things with closures.

On the other hand, partial and decorator are particular purposes. Maybe they use closures. Maybe they don't. That's an implementation detail, and you don't need to worry about it. What's important is that they achieve the result you want.

Consider a partial. (Ignoring **kwargs.) One way to create it would be to use a closure:

There's no closure here, just a variable that holds a reference to the other variables. But I get the partial behavior, so who cares?

The same is true for decorators. A decorator might be a closure, or it might not. For example, one recent question involved running str.format on a function's __doc__ strings. That was just a case of accepting a function object, modifying the __doc__ attribute, and returning the same object. Clearly, there's no closure involved in that.

Note that the nested function now only uses explicit parameters, not the closure. You can implement a decorator, which is just a function that takes a function and returns a (usually different) function, using either closures, partial (which is implemented using a closure) or a mix of the two.

You refer to closure as a thing. What exactly is a closure, in your words?
– Darshan ChaudharyMay 5 '16 at 16:36

A closure is the environment available to the function, when it is called, on the basis of where it was created. Note that in your closure version the inner function can access one implicitly, not as an explicit parameter or a global variable, because it was available where the function was created.
– jonrsharpeMay 5 '16 at 16:38