Hi Luis,
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.
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.)
* With closures:
===
def myfunc():
pseudo_static_list = []
def real_function(args):
pseudo_static_list.append(args)
print pseudo_static_list
return real_function
myfunc = myfunc()
That's interesting -- I'll need to study it further before I really
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.)
Caveat: you cannot assign, as in python 2.5 at least, to the closure
variable -
doing so would create a local variable instead.
Makes sense.
* With default argument:
===
def myfunc(normal_args, _hidden_arg=[]):
_hidden_arg.append(normal_args)
print _hidden arg
===
(You can't shouldn't to _hidden_arg either, and you risk someone
invoking the
function with that argument)
Right, that was my first idea. Though it's in the "gentleman's
agreement" spirit of Python.
* With function's instance members:
===
def myfunc(args):
myfunc.counter=1 # well, you should use some logic to see if it's
not
# initialized
myfunc.counter+=1
print myfunc.counter
That was my second idea.
Instance attributes beats them all, though.
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.
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.
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.
OT: Please enlighthen me. I didn't grew with C, and even when I saw C
++,
instance variables made a lot more sense to me that 'static'
variables.
Maybe a couple examples will help:
1. You have an instance method whose job it is to map something to
something else (e.g. zip codes to city names), say by looking it up in
a big file or database. Per the "lazy initialization" strategy, you
don't want to look stuff up before it's needed, but you find that
looking it up every time causes big performance problems (because
whatever zip codes are in use at the time get used a lot, and the file
or DB access is slow). Moreover, the object is lightweight and you're
going to have a lot of them coming and going, so just caching the
result on the instance won't help much. You instead need a cache that
sticks around for the life of the app, like a class or module
attribute. But because the existence of that cache is an
implementation detail internal to this method, and shouldn't be
anybody else's business, you want to tuck it away inside that method.
2. You have an object which, among other things, can create other
objects. Part of its job is to assign the newly created objects ID
numbers which must be unique across the entire application (maybe
they're wx identifiers or used for serialization or whatever). So it
needs to keep track of what the next available ID is. But again, if
you consider that to be implementation detail internal to the factory
method, then it should be encapsulated inside that method. And
storing it on the factory-object instance won't do, because you need
the IDs to be unique even across instances.
If you don't understand that, or are happy without having the
choice, and have no answer to the question I
was asking, then that's fine.
I believe he had an answer... You didn't like it, though.
If he had an answer to the question I was asking, he didn't share it.
I asked "what's the best way to do this?" Several responses ignored
that question, and instead said, "Don't do that."
If you ask me how to cook an omelet, I might say "don't eat omelets;
pancakes are much tastier, you should eat them instead." But that
doesn't tell you how to cook an omelet, does it?
I hope mine was more palatable to you.
Yours was tasty indeed, thanks very much!
Cheers,
- Joe
--
http://mail.python.org/mailman/listinfo/python-list