Quoting Joe Strout <joe@strout.net >:
Hi Luis,
A static variable IS encapsulation. Encapsulation happens at many
levels: module, class, instance, and (in languages that support it)
method. A static local variable is simply the finest level of
encapsulation. (Well, actually you could go one finer in some
languages and have block-level static scope.)
A lot of languages have ditched the "concept" of a static variable
on a method (how do
you parse that sentence, btw?) in favour of using encapsulation.
on a method (how do
you parse that sentence, btw?) in favour of using encapsulation.
levels: module, class, instance, and (in languages that support it)
method. A static local variable is simply the finest level of
encapsulation. (Well, actually you could go one finer in some
languages and have block-level static scope.)
for more than one meaning, but I'll agree that it is a C++ problem and not a
problem with the concept. I wish I remembered how and if LISP did it, though.
Being LISP, I'd guess their implementation is also based on closures.
* With closures:
===
def myfunc():
pseudo_static_l ist = []
def real_function(a rgs):
pseudo_static_l ist.append(args )
print pseudo_static_l ist
return real_function
myfunc = myfunc()
===
def myfunc():
pseudo_static_l ist = []
def real_function(a rgs):
pseudo_static_l ist.append(args )
print pseudo_static_l ist
return real_function
myfunc = myfunc()
understand it, so thanks very much. (That's why I ask these
questions; I'm hoping there is some Python feature I haven't yet fully
grokked which applies to the problem at hand.)
No, just adding an instance attribute to the class the method is
already on does not give you the same semantics at all, unless the
class happens to be a singleton. Otherwise, each instance would get
its own cache (or count or whatever -- there are several different use
cases I've seen for this), rather than a shared one. Sometimes that's
acceptable, but often it's not.
already on does not give you the same semantics at all, unless the
class happens to be a singleton. Otherwise, each instance would get
its own cache (or count or whatever -- there are several different use
cases I've seen for this), rather than a shared one. Sometimes that's
acceptable, but often it's not.
One of the things I dislike about 'static' is precisely that it would define the
variable's lifetime as 'forever, everywhere'. But as you say, that may not be
the only answer. You could need 'as long as _this function_ lives' (python gives
you closures for that), 'as long as this object lives' (instance attributes),
'as long as this object's class lives' (class attribute), 'forever' (a global,
or a class attribute of a fixed class, that would be like a global but with a
namespace).
Btw, you can yank a function out of an object and put it on another, if you need
your counters to survive that, use closures, if you need your counters todie in
that case, you'll have to stick with class or instance attributes.
As noted before, the obvious solution in this case is to use a module-
or class-level variable, prefixed with an underscore. That's not
horrible, but I wanted to explore possible alternatives.
or class-level variable, prefixed with an underscore. That's not
horrible, but I wanted to explore possible alternatives.
I understand very well when data should be stored as instance data,
and when it
should be instead tucked away as static data within a method.
and when it
should be instead tucked away as static data within a method.
++,
instance variables made a lot more sense to me that 'static'
variables.
I hope mine was more palatable to you.
--
Luis Zarrabeitia
Facultad de Matemática y Computación, UH