Function decorator that caches function results

Diez B. Roggisch deets at nospam.web.de
Mon Oct 10 00:11:02 CEST 2005


> 
> [penny drops] Now we're getting somewhere... a closure is something
> _added_ to a function. So we should talk about functions-without-closures
> and functions-with-closures.

Yes.

> 
> 
>>Speaking in 
>>terms of "is a" could be seen as some inheritance relation. 
> 
> 
> [penny rises again] Dammit, just when I thought I got it. So a closure is
> like a subclass of function? Functions are a higher level classification,
> like mammals. There are mammals that are primates (functions that _are_
> closures) and mammals that aren't (functions that _aren't_ closures).
> 

Hrmpf. No, I wanted to say the exact opposite. My bad - just ignore that 
paragraph of mine in the earlier post, ok?


> Right! So closures are something which functions _have_ -- which is why
> Python functions have an attribute called func_closure, which is empty in
> functions without closures, and contain a tuple of cells in those with
> them.

Yes.

> 
> Now somebody is going to tell me this is an implementation detail and it
> isn't true in the general language independent case...

Paul Rubin did so, and I guess it is, although I don't know for sure.

> Now you're trying to trick me... they are both *instances* of Foo, not
> Foo. Foo is a class, and f and g are not classes, let alone the same class.

As two functions are instances of the "class of functions". I just 
wanted to point out that two instances of one class can have differnet 
state. The analogy isn't perfect, as this special state "closure" isn't 
available easily for you to alter, and gets created behind the scenes. 
But as each function with a closure is created on the fly - same code, 
different closure data - it sort of fitted, I hoped.

> 
> 
>>- but one has a different attribute set. And if Foo
>>had some semantics that did something different based on bar, would you
>>also say they're supposed have two different classes? You could in fact
>>do that - create one class for each incarnation of possible  state. But
>>then the concept of classes and objects gets somewhat blurred, as each
>>instance would have its own class. The same is true for functions.
> 
> 
> Ah, but in languages like Pascal that can take functions as arguments, but
> can't return functions as output, *all* functions have to be created
> separately. To take your analogy and run with it, Pascal would be like a
> language that didn't allow f and g to have different attributes unless
> they belonged to different classes.
> 
> Python is not like that, which is why you can write a function to return
> functions (a factory function?). If the output function needs access to
> the namespace of the factory function, Python adds a closure to that
> output function, giving it access to the objects in that namespace.

Hm, no. You can return functions in other languages, e.g. C. Don't know 
pascal good enough. But they will always be the same without any state 
associated to them, whereas in python you have some state. The same way 
as bound methods know about their first arguments, functions with 
closures know about - well, their closure :)

A closure is really only an environment, adding values to locals() - 
implemented as cells in python - that adds to the local variables when 
the function is executed, and is dynamically created when a function 
with a closure is defined. This works because of the interpreted nature 
of python.


Regards,

Diez



More information about the Python-list mailing list