Re: using "private" parameters as static storage?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Joe Strout

    Re: using "private" parameters as static storage?

    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_l ist = []
    def real_function(a rgs):
    pseudo_static_l ist.append(args )
    print pseudo_static_l ist
    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_a rgs, _hidden_arg=[]):
    _hidden_arg.app end(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

Working...