Nudged by the dot syntax, I was thinking of this function attribute as
if it were a sort of class member (i.e., pretending for a while this
function is a class) and, since functions can't have instances, treating
it as a sort of static member of the function, which should be available
as soon as declared.
There is no declaration in Python; you just create attributes by
binding objects to names.
Obviously I got it all wrong. Instead, they work like local
variables except that they "persist" after the function has exited.
Hmmm. No. Functions are first class objects, and you can dynamically
add attributes to them as you go along (as is the case for many, but
not all, other types of objects).
Do you realize that the foo identifier you used in your example is not
inextricably linked to any function whose name is foo? The name of a
function, and the variables to which it is bound are two different
concepts.
Consequently, the foo.a in the function body only _coincidentally_
refers to an attribute of the function in which it appears.
Consider:
Traceback (most recent call last):
File "<stdin>", line 1, in ?
The error at "bar(4)" in the above should hint at the fact that the
"foo" in "foo.a" in the definition of the function foo, does not refer
to the function itself but to whatever object which happens to be
bound to the name "foo" at the time the function is being exectuted.
What are they used for? Give me a compelling reason to have such a
beast in the language.
Now there's a good question
I haven't found a use for these
myself ... but then I haven't looked very hard for one.
Given that function attributes were added to the language (in version
2.1 or 2.2 ?), I guess someone felt a need for them, and Guido agreed.